Exercicis
Exercici 2_1
Aquest primer exercicis és per a tractament de bytes, ja que es tractarà de modificar una imatge. Per a poder provar-lo podeu utilitzar la imatge Penyagolosa.bmp que se us proporciona en l'aula virtual i l'heu de copiar al directori arrel del projecte Tema2 per a un funcionament més còmode.
No es pretén construir un editor d'imatges. Tan sols pretenem agafar la informació del fitxer byte a byte, reslitzar alguna transformació en els bytes i guardar-la en un altre fitxer.
El format d'un fitxer bmp, aproximadament és el següent:
- En els 54 primers bytes es guarda informació diversa, com la grandària de la imatge, paleta de colors, ...
- A partir d'ahí es guarda cada punt de la imatge com 3 bytes, un per al roig (R), un per al verd (G) i i un per al blau (B), anant d'esquerra a dreta i de dalt a baix.
Copia't i modifica la classe fitxerImatge, creant els mètodes oportuns seguint aquestes pautes:
- El constructor fitxerImatge(File fEnt) ha d'inicialitzar la propietat f (File) si i només si existeix el fitxer i l'extensió del fitxer és .bmp (ho controlarem senzillament perquè el nom del fitxer acaba així). En cas contrari, traure els missatges d'error oportuns per l'eixida estàndar.
- Els mètodes de transformació (transformaNegatiu, transformaObscur i el voluntari transformaBlancNegre) han de crear un nou fitxer que contindrà la imatge transformada com veurem més avant. El nom del nou fitxer s'ha de formar a partir del nom del fitxer d'entrada, el que hem guardat en el constructor. Serà sempre posant abans del .bmp un guió baix i un identificatiu de la transformació realitzada: _n per al negatiu, _o per a l'obscur i _bn per al blanc i negre (part voluntària). És a dir, si el fitxer d'entrada fóra imatge1.bmp, el d'eixida haurà de ser:
- imatge1_n.bmp per al mètode transformaNegatiu
- imatge1_o.bmp per al mètode transformaObscur
- imatge1_bn.bmp per al mètode voluntari transformaBlancNegre
- En cada transformació, els primers 54 bytes s'han de copiar sense modificar: s'han d'escriure en el fitxer de destí tal i com s'han llegit del fitxer d'entrada
- A partir del 54, cada vegada que es llegirà un byte, s'haurà de transformar abans d'escriure'l en el destí. La transformació és d'aquesta manera:
- Per al negatiu (transformaNegatiu), cada byte de color (RGB) de cada punt, s'ha de transformar en el complementari. Com estem parlant de bytes però que en llegir els guardem en enters, senzillament serà calcular 255 - b (si b és el byte llegit).
- Per a l'obscur (transformaObscur), cada byte de color (RGB) de cada punt, s'ha de baixar d'intensitat a la meitat. Senzillament serà calcular b / 2 (si b és el byte llegit).
- Per al blanc i negre (transformaBlancNegre), que és el voluntari, hem de donar el mateix valor per al roig, el blau i el verd (RGB) de cada punt, i així aconseguirem un gris d'intensitat adequada. Una bona manera serà llegir els tres bytes de cada punt (no s'aconsella utilitzar una lectura amb un array de 3 posicions; millor fer tres lectures guardades en tres variables diferents), calcular la mitjana d'aquestos 3 valors, i escriure el resultat 3 vegades en el fitxer de destí.
A mode orientatiu del que es vol fer, us adjunte la classe fitxerImatge a la qual heu de modificar el constructor i els tres mètodes de transformació (l'últim és voluntari). Recordeu que ha d'anar al paquet Exercicis.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class fitxerImatge {
File f = null; // en f és on es guardarà la referència del fitxer
public fitxerImatge(File fEnt){
// Control d'existència del fitxer i control de l'extensió .bmp (traure missatges d'error)
// En cas que tot siga correcte, inicialitzar f amb fEnt
}
public void transformaNegatiu() throws IOException{
// Transformar a negatiiu i guardar en _n.bmp
}
public void transformaObscur() throws IOException{
// Transformar a una imatge més fosca i guardar en _o.bmp
}
/* Part voluntària
public void transformaBlancNegre() throws IOException{
// Transformar a una imatge en blanc i negre i guardar en _bn.bmp
}
*/
}
Aquest seria un exemple de programa principal, que podeu utilitzar si voleu. Recordeu que ha d'anar al paquet Exercicis.
import java.io.File;
import java.io.FileNotFoundException;
public class Exercici_2_1 {
public static void main(String[] args) throws IOException {
File f = new File("Penyagolosa.bmp");
fitxerImatge fi = new fitxerImatge(f);
fi.transformaNegatiu();
fi.transformaObscur();
// voluntari
// fi.transformaBlancNegre();
}
}
Per a la imatge que se us proporciona (i que està en la construcció del File del programa principal), que és la de l'esquerra, haurien d'eixir les de la dreta:
| Imatge inicial | negatiu | obscur | blanc i negre (voluntari) |
![]() |
![]() |
![]() |
![]() |
| Penyagolosa.bmp | Penyagolosa_n.bmp | Penyagolosa_o.bmp | Penyagolosa_bn.bmp |
Exercici 2_2
Aquest programa serà el primer que utilitzarà components gràfics.
Per a entendre els components gràfics de la llibreria Swing i els contenidors de la llibreria Awt, que són els que utilitzarem, us aconselle que us mireu l'annex Gràfics en Java: llibreries AWT i SWING que teniu en la secció d'annexos, al final del curs de Moodle. De tota manera, us proporcione "l'esquelet" del programa, i només us deman
Anem a fer un senzill editor de text amb el següent aspecte:

En el JTextField posarem el nom (i ruta) del fitxer.
- Quan apretem al botó Obrir ha de bolcar el contingut del fitxer al JTextArea (controlant prèviament que existeix el fitxer).
- Quan apretem a Guardar, ha de bolcar el contingut del JTextArea en el fitxer (el nom del qual tenim en el JTextField).
L'esquelet del programa és el que trobareu a continuació. He utilitzat la filosofia de l'annex, que consisteix a tenir un programa principal (el main) que l'únic que fa és utilitzar un objecte de la classe que hereta de JFrame, que és realment la finestra.
Una vegada copiats en el paquet Exercicis del projecte Tema2, només heu de completar el que teniu al final de tot, al mètode actionPerformed
import java.io.IOException;
public class Exercici_2_2 {
public static void main(String[] args) throws IOException {
final Exercici_2_2_Pantalla finestra = new Exercici_2_2_Pantalla();
finestra.iniciar();
}
}
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Exercici_2_2_Pantalla extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
JLabel et_f = new JLabel("Fitxer:");
JTextField fitxer = new JTextField(25);
JButton obrir = new JButton("Obrir");
JButton guardar = new JButton("Guardar");
JLabel et_a = new JLabel("Contingut:");
JTextArea area = new JTextArea(10, 50);
JScrollPane scrollPane = new JScrollPane(area);
// en iniciar posem un contenidor per als elements anteriors
public void iniciar() {
getContentPane().setLayout(new GridLayout(2, 1));
setTitle("Editor de text");
JPanel panell1 = new JPanel(new GridLayout(0, 1));
JPanel panell1_1 = new JPanel(new FlowLayout());
panell1.add(panell1_1);
panell1_1.add(et_f);
panell1_1.add(fitxer);
JPanel panell1_2 = new JPanel(new FlowLayout());
panell1.add(panell1_2);
panell1_2.add(obrir);
panell1_2.add(guardar);
JPanel panell2 = new JPanel(new GridLayout(0, 1));
panell2.add(scrollPane);
area.setEditable(true);
getContentPane().add(panell1);
getContentPane().add(panell2);
setVisible(true);
pack();
obrir.addActionListener(this);
guardar.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == obrir) {
// Instruccions per a bolcar el contingut del fitxer en el JTextArea
}
if (e.getSource() == guardar) {
// Instruccions per a guardar el contingut del JTextArea al fitxer. No us oblideu de tancar el flux d'eixida.
}
}
}
Nota
En l'operació de guardar, no us oblideu de tancar el flux d'eixida per assegurar-vos que s'escriu en el fitxer
Exercici 2_3. Voluntari
Com a exercici voluntari us propose una altra versió del Editor de Text de l'anterior exercici.
Ara serà únicament un JTextArea, i les opcions les tindrem en menú. Utilitzeu el component JFileChooser per a buscar fitxers i per a guardar-los que ens proporciona Swing. Ja teniu implementada l'opció d'eixir.

Si teniu temps i ganes, afegiu un component baix de tot per a triar la codificació entre UTF-8 i ISO-8859-15
Aquest seria l'esquelet del programa principal i la classe que implementa JFrame:
import java.io.IOException;
public class Exercici_2_3 {
public static void main(String[] args) throws IOException {
final Exercici_2_3_Pantalla finestra = new Exercici_2_3_Pantalla();
finestra.iniciar();
}
}
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
public class Exercici_2_3_Pantalla extends JFrame implements ActionListener{
JTextArea area = new JTextArea();
JScrollPane scrollPane = new JScrollPane(area);
JMenuBar menu_p = new JMenuBar();
JMenu menu_arxiu = new JMenu("Arxiu");
JMenu menu_ajuda = new JMenu("Ajuda");
JMenuItem obrir = new JMenuItem("Obrir");
JMenuItem guardar = new JMenuItem("Guardar");
JMenuItem guardarCom = new JMenuItem("Guardar com ...");
JMenuItem eixir = new JMenuItem("Eixir");
JMenuItem quantA = new JMenuItem("Quant a Editor");
JFileChooser fCh = new JFileChooser();
public void iniciar(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setLayout(new BorderLayout());
this.setTitle("Editor de text");
this.getContentPane().add(scrollPane,BorderLayout.CENTER);
this.setSize(750, 400);
this.setJMenuBar(menu_p);
menu_p.add(menu_arxiu);
menu_p.add(menu_ajuda);
menu_arxiu.add(obrir);
menu_arxiu.add(guardar);
menu_arxiu.add(guardarCom);
menu_arxiu.add(new JSeparator());
menu_arxiu.add(eixir);
menu_ajuda.add(quantA);
this.setVisible(true);
obrir.addActionListener(this);
guardar.addActionListener(this);
guardarCom.addActionListener(this);
eixir.addActionListener(this);
quantA.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if ((e.getSource() == eixir))
System.exit(0);
}
}
Llicenciat sota la Llicència Creative Commons Reconeixement NoComercial CompartirIgual 2.5



