elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Tutorial básico de Quickjs


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Error al guardar imagen PGM P2
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Error al guardar imagen PGM P2  (Leído 2,772 veces)
AdrianGL13

Desconectado Desconectado

Mensajes: 1


Ver Perfil
Error al guardar imagen PGM P2
« en: 31 Mayo 2018, 07:26 am »

Hola, buenas noches. Espero alguien me pueda ayudar con este problema.

Necesito realizar un programa en C++ en el cual ingrese una imagen PGM P2, la lea, cree una copia, la pase a negativo (invertir) y la guarde.

Tengo este código y compila, sin embargo al momento de guardar, la imagen arroja valores muy extraños, en lugar de ser números, da letras o símbolos. Ya intente cambiar valores char a int pero sigue sin funcionar. Espero alguien me pueda ayudar. Muchas gracias.

Código:
include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <math.h>
#include <ctime>
#include <time.h>

using namespace std;

typedef struct imagen
{
    char nombre[200];
    int comentarios;
    int ancho;
    int alto;
    int escala;
    unsigned char im[1000][1000];
}
IMAGEN;

int tipo_imagen(char *nombre)
{
    FILE *archivo;

    unsigned char c1, c2;

    archivo = fopen(nombre,"r");

    if(archivo == NULL)
    {
        return 0;
    }

    c1 = fgetc(archivo);
    c2 = fgetc(archivo);

    fclose(archivo);

    if((c1=='P') && (c2=='2'))
    {
        cout<<"ARCHIVO CARGADO"<<endl;
        return 1;
    }
    else
    {
        cout<<"ERROR - Imagen no soportada"<<endl;
        return 2;
    }
}

IMAGEN leer_imagen(char *nombre)
{
    IMAGEN imagen;
    unsigned int c1, c2;
    unsigned char caracter;

    FILE *archivo;

    int i, j, ancho, alto, escala;

    archivo = fopen(nombre, "r");

    c1 = fgetc(archivo);
    c2 = fgetc(archivo);
    fgetc(archivo);

    caracter = fgetc(archivo);
    imagen.comentarios = 0;
    while(caracter=='#')
    {
        imagen.comentarios = imagen.comentarios + 1;
        caracter = fgetc(archivo);
        while(caracter != '\n')
        {
            caracter = fgetc(archivo);
        }
        caracter = fgetc(archivo);
    }

    ungetc(caracter,archivo);
    fscanf(archivo,"%d%d",&ancho,&alto);
    fscanf(archivo,"%d",&escala);
    imagen.ancho = ancho;
    imagen.alto = alto;
    imagen.escala = escala;
    strcpy(imagen.nombre,nombre);
    for(i=0; i<imagen.alto; i++)
    {
        for(j=0; j<imagen.ancho; j++)
        {
            caracter = fgetc(archivo);
            imagen.im[i][j] = caracter;
        }
    }
    fclose(archivo);
    return(imagen);

    cout<<"ARCHIVO LEIDO"<<endl;
}

void mostrar_datos_imagen(IMAGEN *imagen)
{
    cout<<"DATOS DE ARCHIVO"<<endl;
    printf("\nNombre: %s",imagen->nombre);
    printf("\nComentarios : %d",imagen->comentarios);
    printf("\nAncho : %d",imagen->ancho);
    printf("\nAlto  : %d",imagen->alto);
    printf("\nEscala: %d\n",imagen->escala);
}

IMAGEN duplica_imagen(IMAGEN *imagen)
{
    IMAGEN duplica;
    int i,j;

    strcpy(duplica.nombre,"Dup_");
    strcat(duplica.nombre,imagen->nombre);
    duplica.comentarios = imagen->comentarios;
    duplica.ancho = imagen->ancho;
    duplica.alto = imagen->alto;
    duplica.escala = imagen->escala;
    for(i=0; i<imagen->alto; i++)
    {
        for(j=0; j<imagen->ancho; j++)
        {
            duplica.im[i][j]=imagen->im[i][j];
        }
    }
    return duplica;

    cout<<"ARCHIVO DUPLICADO"<<endl;
}

void invertir_imagen(IMAGEN *imagen)
{
    int i,j;
    for(i=0; i<imagen->alto; i++)
    {
        for(j=0; j<imagen->ancho; j++)
        {
            imagen->im[i][j]=255 - imagen->im[i][j];
        }
    }

    cout<<"ARCHIVO INVERTIDO"<<endl;
}

void grabar_imagen(IMAGEN *imagen)
{
    int i,j;
    unsigned char c;
    FILE *copia;

    copia=fopen(imagen->nombre,"w");

    fprintf(copia,"P2\n");
    fprintf(copia,"#Creado por NanoGrupito\n");
    fprintf(copia,"%d %d\n",imagen->ancho,imagen->alto);
    fprintf(copia,"%d\n",imagen->escala);

    for(i=0; i<imagen->alto;i++)
    {
        for(j=0; j<imagen->ancho; j++)
        {
            c=imagen->im[i][j];
            fputc(c,copia);
        }
    }

    fclose(copia);

    cout<<"ARCHIVO GRABADO"<<endl;
}

int main()
{
    char nombre[200];
    int imagen_tipo;
    IMAGEN imagen;
    IMAGEN imagen_analizada;

    cout<<"Ingresa el nombre de la imagen"<<endl;
    cin>>nombre;

    imagen_tipo = tipo_imagen(nombre);

    if(imagen_tipo==1)
    {
        imagen = leer_imagen(nombre);
        mostrar_datos_imagen(&imagen);
        imagen_analizada = duplica_imagen(&imagen);
        mostrar_datos_imagen(&imagen_analizada);
        invertir_imagen(&imagen_analizada);
        grabar_imagen(&imagen_analizada);
    }
}


En línea

srWhiteSkull


Desconectado Desconectado

Mensajes: 444



Ver Perfil WWW
Re: Error al guardar imagen PGM P2
« Respuesta #1 en: 31 Mayo 2018, 12:20 pm »

Con el fopen deberías trabajar en modo binario para esas cosas pero en teoría los valores da igual que sean caracteres o numéricos pues eso es simplemente la forma en la que son representados. Los valores internamente se manejan en registros de varios bits (depende de la arquitectura).

http://www.cplusplus.com/reference/cstdio/fopen/


« Última modificación: 31 Mayo 2018, 12:23 pm por srWhiteSkull » En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Error al guardar imagen PGM P2
« Respuesta #2 en: 31 Mayo 2018, 13:33 pm »

Es cierto. Pero tiene al menos tres enteros, y sabiendo que son de 4 bytes cada uno pues sí, debería ser un archivo binario.
En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.355


Ver Perfil
Re: Error al guardar imagen PGM P2
« Respuesta #3 en: 31 Mayo 2018, 18:05 pm »

No he repasado tod el código, me he detenido donde ya he visto errores...

Hasta donde yo sé, el formato PGM la cabecera es muy sencilla y no incluye un campo llamado 'escala'. No había visto la estructura y el nombre elegido, se presta a confusión...

Código:
Estructura CabeceraPGM
    Magic       // dos bytes "P2" ó "P5" para formato ASCII y binario respectivamente.
    Ancho     // píxeles de ancho en formato ASCII.
    Alto          // Ídem de alto    "
    NivelesGris   // cantidad de niveles de grises usados -1. Es decir un valor 255, implica 256 niveles de gris.
fin estructura

Y luego vienen los datos... a razón de 3 bytes (caracteres, digitos por píxel)... es decir
Si el primer píxel tiene el valor 82, en el fichero aparece " 82"
Si luego le siguen píxeles con estos valores: 7, 123, 94, 5, 0 210, estará así escrito tal cual lo ves aquí (a continuación), igual si lo abres con el bloc de notas...
   " 82  7123 94  5  0210"

Y efectivamente saltando las líneas de comentarios, que empiezan con sharp '#' y acaba en la propia línea (hasta encontrar el salto de línea). Aunque no hay restricción en esa cantidad de caracteres de comentarios típicamente se limita a no más de 70, pero no conviene fiarse de ese valor, pués es solo una sugerencia del creador.

Fíjate que al comienzo de cada línea de la imagen es valído ambas situaciones: para un valor 7, 22, 33
"  7 22 33"
" 7 22 33"
"7 22 33"
Es decir el primer píxel de una línea no exige los 3 caracteres, porque el valor podrá leerse sin ambigüedad, puede tener un espacio, 2 o ninguno. Nota además que esto es válido para cualquier línea, es decir una puede tener las 3 cifra, otra 2 y otra 1... aunque debe leerse así, para escribir, conviene que todas tengan la misma cantidad, porque el objetivo primordial de estos formatos es poder abrirlos y editarlos con el bloc de notas. Una desalineación al comienzo, puede complicar precisamente la edición y claridad de la imagen.

Rehaz de nuevo tu código para leer correctamente de esta manera y si sigues teniendo errores pasa a preguntar de nuevo...


mmm... acabo de ver la estructura que tenías y por tanto con 'escala', no te estés refiriendo a nada relativo a la imagen si no a los niveles de grises, que has querido llamar 'escala de grises', pero acortado... ok...

Nota que cuando, niveles de gris (escala), es distinto de 255, exigirá interpolar los valores, es decir si en origen una imagen tiene el valor 255 y ahora tu lo reduces a solo 8 niveles de gris, al ir los valores entre 0 y 7, deberás dividir cada valor entre 32, ya que 256/8 = 32... (para escribir en fichero, para mostrar la imagen siempre habrá que hacerlo en el rango 0-255)

...pero igualmente se seguirán necesitando SIEMPRE 3 digitos para representar en fichero el valor de cada píxel...
« Última modificación: 31 Mayo 2018, 18:21 pm por NEBIRE » En línea

srWhiteSkull


Desconectado Desconectado

Mensajes: 444



Ver Perfil WWW
Re: Error al guardar imagen PGM P2
« Respuesta #4 en: 31 Mayo 2018, 22:41 pm »

Además a mi parecer el código no es bueno, porque encima reserva memoria estática en la misma estructura sin haberlo usado o sin tener nada (tanto para el nombre como los datos, el im). De esa forma está tomando memoria de la pila y es raro que la aplicación no se te rompa al ejecutarla a no ser que hayas modificado el tamaño de esta en el compilador.

Lo normal es que trabajes con punteros, con memoria dinámica. La estructura debería quedar algo así:

Código
  1. ...
  2. typedef struct {
  3. char * nombre;
  4. int comentarios;
  5. int ancho;
  6. int alto;
  7. int escala;
  8. unsigned char * datos;
  9. } IMAGEN;
  10.  
  11. // luego definir un objeto IMAGEN
  12. IMAGEN miImagen;
  13.  
  14. // luego una vez sabes el tamaño, mirando la cabecera, calculas la memoria que necesitas y la reservas
  15. int ancho=320, alto=200;
  16. miImagen.datos = (unsigned char*)malloc(sizeof(char)*(ancho*alto));
  17.  
  18. // luego para recorrer el puntero como si fuera la pantalla haces
  19. miImagen.datos[x*ancho+y]=255;
  20.  
  21. char pixel = miImagen.datos[x*ancho+y];
  22. ...
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
guardar imagen
Programación Visual Basic
Malkavian_71 1 1,817 Último mensaje 5 Octubre 2005, 06:05 am
por Slasher-K
guardar imagen capturada
Programación Visual Basic
soru13 1 1,211 Último mensaje 23 Junio 2006, 18:27 pm
por NYlOn
Guardar Imagen del Clipboard
.NET (C#, VB.NET, ASP)
Keyen Night 1 2,585 Último mensaje 7 Agosto 2009, 02:36 am
por seba123neo
guardar imagen
PHP
kakashi20 1 1,794 Último mensaje 21 Septiembre 2012, 01:17 am
por дٳŦ٭
guardar una imagen bmp
Programación C/C++
m@o_614 0 1,500 Último mensaje 20 Noviembre 2015, 17:53 pm
por m@o_614
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines