Frage bei der Konvertierung vom PNG-Bild zum JPG-Bild mit Libpng

hanow_de

Grünschnabel
Guten Abend, Alle

Ich wollte ein Programm schreiben, das eine Konvertierung vom PNG-Bild zum JPG-Bild macht. Bisher habe ich folgendes getan:

1. png.h eingebunden;

2. read-Funktion geschrieben wie folgendes:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <inttypes.h>

#include "png.h"

#include "pngio.h"
#include "error.h"
#include "image.h"


/*==============================================================================*
 *  read_png    	    			                                            *
 *==============================================================================*/

int x, y;

int width, height;

int channels;

png_byte color_type;
png_byte bit_depth;

png_structp png_ptr;
png_infop info_ptr;
int number_of_passes;
png_bytep *row_pointers;



png_uint_32 w, h;
size_t npixels;
//png_uint_32* raster;
//png_uint_32




int read_png (char * input_filename, picture *thePicture, FILE *status_log)
{
	int err = no_err;	

	char header[8];    // 8 is the maximum size that can be checked

        /* open file and test for it being a png */
        FILE *fp = fopen(input_filename, "rb");
        if (fp){		

		//abort_("[read_png_file] File %s could not be opened for reading", file_name);
		
		fread(header, 1, 8, fp);

		/* checked out with a proper PNG signature */
		if (png_check_sig(header, 8)){

			/* initialize stuff */
			png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

			if (png_ptr){

				info_ptr = png_create_info_struct(png_ptr);
				if (info_ptr){

					
					if (setjmp(png_jmpbuf(png_ptr))){

						fprintf(status_log, "Error during init_io. \n");

					}else{
						
						//takes our file stream pointer(fp) and stores it in the png_ptr struct for later use.
						png_init_io(png_ptr, fp);
						//lets libpng know that we already checked the 8 signature bytes
						png_set_sig_bytes(png_ptr, 8);

						//information is stored in the information struct
						png_read_info(png_ptr, info_ptr);

						//png_read_update_info(png_ptr, info_ptr);

						width = png_get_image_width(png_ptr, info_ptr);
						height = png_get_image_height(png_ptr, info_ptr);

						//w = png_get_image_width(png_ptr, info_ptr);
						//h = png_get_image_height(png_ptr, info_ptr);

						fprintf(status_log,"png-image-details: width=%i - height=%i\n",width,height);

						//npixels = width * height;
						npixels = width * height;
						

						/* Read the whole image into memory at once. */
						
						/* read file */
						if (setjmp(png_jmpbuf(png_ptr)))

							fprintf(status_log, "Error during read_image. \n");
						

						png_uint_32 *raster = malloc(npixels * 4 *sizeof(png_uint_32));

						//row_pointers = (png_bytep*) malloc(npixels * sizeof(png_bytep));
						row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
						
						for (y=0; y<height; y++)
							row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
						
						png_read_image(png_ptr, row_pointers);						

						
						if(raster != NULL){
							
							
							channels = png_get_channels(png_ptr, info_ptr);
							fprintf(status_log,"Bild-Kanal ist %d .\n", channels);

							fprintf(status_log,"Bild ist geladen\n");

							thePicture->pixelmap = row_pointers;
							thePicture->width = width;
							thePicture->height = height;
							thePicture->type = png_type;
							

						}else{

								fprintf(status_log,"Memory error.\n");
								err = mem_err;

						}
						fclose(fp);

					}
					

				}else{
					fprintf(status_log, "png_create_info_struct failed. \n");
					//err = mem_err;
				}

			}else{

				fprintf(status_log, "png_create_read_struct failed. \n");
			}


		}else{

			fprintf(status_log, "checking PNG failed. \n");

		}
		        
	}else{

		fprintf(status_log,"Error. Fail to open the png.\n");
		err = file_err;

	}


	return err;

}


3. Mein Problem ist dass die Konvertierung nicht richtig funktioniert. seh bitte folgende Bilder:


PNG-Bild: startrek.png

JPG-Bild: st2013.jpg

Kann mir jemand Tipps geben woran es liegen könnte und was für Funktionen von der Bibliotheken ich noch brauche?

Herzlichen Dank.

Schönen Abend.

Freundliche Grüße.
 
Hallo,
ich kenne mich mit der lib leider nicht aus, da könnten dir andere sicher besser helfen.

Allerdings vermute ich stark (aufgrund des Resultates), dass deine Kanäle der Bilder nicht übereinstimmen.
Während png einen Alpha-Kanal unterstützt tut dies JPG in der Regel nicht.

Viele Grüße,
Jennesta
 
Vielen Dank für deine Antwort, Jennesta

Ich weiß nicht ob ich richtig verstehe: -)

Das Bild mit 4 Kanälen werden im Arbeitsspeicher so aussehen: ?

RGBA | RGBA | RGBA | ...

Ich habe eigentlich an anderer Stelle (image.h) schon ein structur für ein Bild mit 4 byte pixel deklariert, es sieht so aus:

Code:
typedef struct pixel3{
 
pixelvalue r;
pixelvalue g;
pixelvalue b;
pixelvalue a;
 
}pixel3



typedef struct pic{

void *pixelmap;
int width;
int height;
int type;

}pic

Im selben Programm wird die Positionen durch get_pixel(koordinaten, image) gerechnet.

In der read_png Funktion wird geprüft, um welchen Bildtyp es sich handelt, also RGB oder RGBA.

Meine Frage:

Wenn der Kanal nicht übereinstimmt, wie sollte ich es korrigieren?

Vielen Dank.

Freundliche Grüße.
 
Zuletzt bearbeitet:
Zurück