Práctica Final. Rutas Aéreas.
imagen.cpp
Ir a la documentación de este archivo.
1 
10 #include "imagen.h"
11 #include "imagenES.h"
12 #include "string.h"
13 #include <cmath>
14 #include <cassert>
15 #include <iostream>
16 
17 using namespace std;
18 
20 {
21  data = 0;
22  nf = nc = 0;
23 }
24 
25 Imagen::Imagen(int f, int c)
26 {
27  nf = f;
28  nc = c;
29  data = new Pixel *[nf];
30  for (int i = 0; i < nf; i++)
31  {
32  data[i] = new Pixel[nc];
33  for (int j = 0; j < nc; j++)
34  {
35  data[i][j].r = 255;
36  data[i][j].g = 255;
37  data[i][j].b = 255;
38  data[i][j].transp = 255;
39  }
40  }
41 }
42 
43 void Imagen::borrar()
44 {
45  for (int i = 0; i < nf; i++)
46  delete[] data[i];
47  delete[] data;
48 }
49 
50 void Imagen::copiar(const Imagen &img)
51 {
52 
53  nf = img.nf;
54  nc = img.nc;
55  data = new Pixel *[nf];
56  for (int i = 0; i < nf; i++)
57  {
58  data[i] = new Pixel[nc];
59  for (int j = 0; j < nc; j++)
60  {
61  data[i][j] = img.data[i][j];
62  }
63  }
64 }
65 
67 {
68  if (this != &img)
69  {
70  borrar();
71  copiar(img);
72  }
73  return *this;
74 }
75 
76 Pixel Imagen::media_pixeles(const Pixel& p1, const Pixel& p2) const{
77  Pixel ret_p;
78  ret_p.r = (p1.r + p2.r) / 2;
79  ret_p.g = (p1.g + p2.g) / 2;
80  ret_p.b = (p1.b + p2.b) / 2;
81  ret_p.transp = 255;
82  return ret_p;
83 }
84 
85 void Imagen::LeerImagen(const char *img_path, const string &mascara_path)
86 {
87  int f, c;
88  unsigned char *aux, *aux_mask;
89 
90  LeerTipoImagen(img_path, f, c);
91  aux = new unsigned char[f * c * 3];
92  LeerImagenPPM(img_path, f, c, aux);
93  if (mascara_path != "")
94  {
95  int fm, cm;
96  LeerTipoImagen(mascara_path.c_str(), fm, cm);
97  aux_mask = new unsigned char[fm * cm];
98  LeerImagenPGM(mascara_path.c_str(), fm, cm, aux_mask);
99  }
100  else
101  {
102  aux_mask = 0;
103  }
104 
105  Imagen img(f, c);
106  int total = f * c * 3;
107  for (int i = 0; i < total; i += 3)
108  {
109  int posi = i / (c * 3);
110  int posj = (i % (c * 3)) / 3;
111 
112  img.data[posi][posj].r = aux[i];
113  img.data[posi][posj].g = aux[i + 1];
114  img.data[posi][posj].b = aux[i + 2];
115  if (aux_mask != 0)
116  img.data[posi][posj].transp = aux_mask[i / 3];
117  else
118  img.data[posi][posj].transp = 255;
119  }
120 
121  *this = img;
122  if (aux_mask != 0)
123  delete[] aux_mask;
124  delete[] aux;
125 }
126 
127 void Imagen::EscribirImagen(const char img_path[]) const
128 {
129  unsigned char *aux = new unsigned char[nf * nc * 3];
130  unsigned char *m = new unsigned char[nf * nc];
131 
132  int total = nf * nc * 3;
133 
134  for (int i = 0; i < total; i += 3)
135  {
136  int posi = i / (nc * 3);
137  int posj = (i % (nc * 3)) / 3;
138 
139  aux[i] = data[posi][posj].r;
140  aux[i + 1] = data[posi][posj].g;
141  aux[i + 2] = data[posi][posj].b;
142  m[i / 3] = data[posi][posj].transp;
143  }
144 
145  if (!EscribirImagenPPM(img_path, aux, nf, nc))
146  {
147  cerr << "Ha habido un problema en la escritura de " << img_path << endl;
148  }
149 
150  delete[] aux;
151 
152  string n_aux = "mascara_";
153  n_aux = n_aux + img_path;
154  size_t found = n_aux.find(".ppm");
155 
156  if (found != string::npos)
157  {
158  n_aux = n_aux.substr(0, found);
159  }
160 
161  n_aux = n_aux + ".pgm";
162 
163  if (!EscribirImagenPGM(n_aux.c_str(), m, nf, nc))
164  {
165  cerr << "Ha habido un problema en la escritura de " << n_aux << endl;
166  }
167 
168 
169  delete[] m;
170 }
171 
172 void Imagen::PutImagen(int posi, int posj, const Imagen & img, Tipo_Pegado t){
173  assert(posi + img.nf < nf && posj + img.nc < nc);
174 
175  for (int i = 0; i < img.nf; i++)
176  for (int j = 0; j < img.nc; j++)
177  if (posi + i >= 0 && posi + i < nf && posj + j >= 0 && posj + j < nc)
178  {
179  if (img(i,j).transp != 0) {
180  if (t == OPACO)
181  (*this).operator()(posi + i, posj + j) = img(i, j);
182  else if (t == BLENDING) {
183  (*this).operator()(posi + i, posj + j) = media_pixeles((*this).operator()(posi + i, posj + j), img(i, j));
184  }
185  }
186  }
187 }
188 
189 const Pixel &Imagen::operator()(int i, int j) const {
190  assert(i >= 0 && i < nf && j >= 0 && j < nc);
191  return data[i][j];
192 }
193 
194 Pixel &Imagen::operator()(int i, int j) {
195  assert(i >= 0 && i < nf && j >= 0 && j < nc);
196  return data[i][j];
197 }
198 
199 Imagen Imagen::Rota(double angulo) const {
200  double rads=angulo;
201  double coseno = cos(angulo);
202  double seno = sin(angulo);
203  //Para obtener las dimensiones de la imagen
204  int rcorners[4],ccorners[4];
205  int newimgrows,newimgcols;
206  double new_row_min,new_col_min,new_row_max,new_col_max;
207  double inter,inter1;
208  rcorners[0]=0;
209  rcorners[1]=0;
210  ccorners[0]=0;
211  ccorners[2]=0;
212  rcorners[2]=getFilas()-1;
213  rcorners[3]=getFilas()-1;
214  ccorners[1]=getColumnas()-1;
215  ccorners[3]=getColumnas()-1;
216  new_row_min=0;
217  new_col_min=0;
218  new_row_max=0;
219  new_col_max=0;
220  newimgrows=0;
221  newimgcols=0;
222  for(int count=0;count<4;count++){
223  inter=rcorners[count]*coseno+ccorners[count]*seno;
224 
225  if(inter<new_row_min)
226  new_row_min=inter;
227  if(inter>new_row_max)
228  new_row_max=inter;
229  inter1=-rcorners[count]*seno+ccorners[count]*coseno;
230 
231  if(inter1<new_col_min)
232  new_col_min=inter1;
233  if(inter1>new_col_max)
234  new_col_max=inter1;
235  }
236 
237  newimgrows=(unsigned)ceil((double)new_row_max-new_row_min);
238  newimgcols=(unsigned)ceil((double)new_col_max-new_col_min);
239 
240  Imagen Iout(newimgrows,newimgcols);
241  for(int rows=0;rows<newimgrows;rows++){
242  for(int cols=0;cols<newimgcols;cols++){
243  float oldrowcos=((float)rows+new_row_min)*cos(-rads);
244  float oldrowsin=((float)rows+new_row_min)*sin(-rads);
245  float oldcolcos=((float)cols+new_col_min)*cos(-rads);
246  float oldcolsin=((float)cols+new_col_min)*sin(-rads);
247  float old_row=oldrowcos+oldcolsin;
248  float old_col=-oldrowsin+oldcolcos;
249  old_row=ceil((double)old_row);
250  old_col=ceil((double)old_col);
251  if ((old_row >= 0) && (old_row < getFilas()) &&
252  (old_col >= 0) && (old_col < getColumnas())) {
253  Iout(rows, cols) = (*this).operator()(old_row, old_col);
254  } else {
255  Iout(rows, cols).r = Iout(rows, cols).g = Iout(rows, cols).b = 255;
256  Iout(rows, cols).transp = 0;
257  }
258  }
259  }
260  return Iout;
261 }
262 
263 // TODO Ambos Iteradores
TDA Imagen.
Definition: imagen.h:65
Pixel & operator()(int i, int j)
Operador de acceso.
Definition: imagen.cpp:194
void EscribirImagen(const char img_path[]) const
Método que escribe una imagen en disco en el archivo dado por nombre.
Definition: imagen.cpp:127
Imagen & operator=(const Imagen &img)
Operador de asignación.
Definition: imagen.cpp:66
void LeerImagen(const char img_path[], const string &nombre_mascara="")
Método que lee una imagen del disco desde el archivo dado por nombre.
Definition: imagen.cpp:85
Imagen Rota(double rads) const
Método que rota una imagen.
Definition: imagen.cpp:199
void PutImagen(int i, int j, const Imagen &img, Tipo_Pegado tp=OPACO)
Método que pega una imagen sobre otra.
Definition: imagen.cpp:172
Imagen()
Constructor por defecto.
Definition: imagen.cpp:19
Fichero cabecera para la E/S de imágenes.
bool EscribirImagenPPM(const char nombre[], const unsigned char datos[], int f, int c)
Escribe una imagen de tipo PPM.
Definition: imagenES.cpp:131
bool LeerImagenPPM(const char nombre[], int &filas, int &columnas, unsigned char buffer[])
Lee una imagen de tipo PPM sobre memoria reservada.
Definition: imagenES.cpp:95
TipoImagen LeerTipoImagen(const char nombre[], int &filas, int &columnas)
Consulta el tipo de imagen del archivo y sus dimensiones.
Definition: imagenES.cpp:77
bool LeerImagenPGM(const char nombre[], int &filas, int &columnas, unsigned char buffer[])
Lee una imagen de tipo PGM sobre memoria reservada.
Definition: imagenES.cpp:113
bool EscribirImagenPGM(const char nombre[], const unsigned char datos[], int f, int c)
Escribe una imagen de tipo PGM.
Definition: imagenES.cpp:147
Fichero cabecera para el TDA Imagen.
Tipo_Pegado
Enumerado para representar el tipo de pegado de una imagen sobre otra.
Definition: imagen.h:54
Estrucutra para representar un pixel de una imagen.
Definition: imagen.h:24
unsigned char r
Componente R de RGB del pixel.
Definition: imagen.h:28
unsigned char transp
Transparencia del pixel.
Definition: imagen.h:45
unsigned char b
Componente B de RGB del pixel.
Definition: imagen.h:38
unsigned char g
Componente G de RGB del pixel.
Definition: imagen.h:33