Permalänk

Ladda PNG

Jag är trött på att använda bmp för grafiken. Det tar så mycket plats.
Hur kan jag ladda PNG? Jag har kollat på libpng.org men jag tycker det är så rörigt. Att skriva en helt egen loader verkar för svårt, då jag inte har någon erfarenhet av något liknande.

Jag vill helst ha lite pedagogisk förklaring, men om ni måste ge mig en länk så länka inte till wotsit.org eller libpng.org, länka till en bra guide på ämnet istället.

Jag ska använda det till ett spel, som använder directdraw. Jag ska alltså ladda en .png fil för att trycka in den i en directdraw-yta.

Tack på förhand!

edit, kan tillägga att jag inte är helt låst på png, andra förslag är också okej. Bara jag slipper sitta med bmp resten av livet

Permalänk
Hedersmedlem

http://libpng.org/pub/png/libpng-manual.txt
Manualen för libpng om du inte hittade den...

Visa signatur

Vim
Kinesis Classic Contoured (svart), Svorak (A5)
Medlem i signaturgruppen Vimzealoter.

Permalänk

Jodå, men tack ändå. Sitter just och experimenterar med det för fullt. Jag insåg att jag nog var tvungen att lära mig använda det :/

Permalänk
Medlem

Hittade det här om det kan vara till hjälp?

Edit: Såg det här också "D3DX8.CreateTextureFromFile allows to load BMP, DDS, GIF, JPG, PNG, and TGA files." Vilket kanske gör livet ännu enklare?

Visa signatur

NAT och FTP borde få ett pannskott och släpas ut i skogen för att mata älgarna med.

Permalänk
Medlem

Lite kod rippat från mitt framework:

bool Image::loadPNG(const char *fileName){ png_structp png_ptr = NULL; png_infop info_ptr = NULL; FILE *file; png_byte pbSig[8]; int iBitDepth, iColorType; png_byte **ppbRowPointers; // open the PNG input file if ((file = fopen(fileName, "rb")) == NULL) return false; // first check the eight byte PNG signature fread(pbSig, 1, 8, file); if (!png_check_sig(pbSig, 8)){ fclose(file); return false; } // create the two png(-info) structures if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr) NULL, (png_error_ptr) NULL)) == NULL){ fclose(file); return false; } if ((info_ptr = png_create_info_struct(png_ptr)) == NULL){ png_destroy_read_struct(&png_ptr, NULL, NULL); fclose(file); return false; } // initialize the png structure png_init_io(png_ptr, file); png_set_sig_bytes(png_ptr, 8); // read all PNG info up to image data png_read_info(png_ptr, info_ptr); // get width, height, bit-depth and color-type png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) &width, (png_uint_32 *) &height, &iBitDepth, &iColorType, NULL, NULL, NULL); depth = 1; nMipMaps = 1; int nChannels = png_get_channels(png_ptr, info_ptr); switch (nChannels){ case 1: format = FORMAT_I8; break; case 3: format = FORMAT_RGB8; break; case 4: format = FORMAT_RGBA8; break; } int rowSize = width * nChannels * iBitDepth / 8; // now we can allocate memory to store the image pixels = new unsigned char[rowSize * height]; // set the individual row-pointers to point at the correct offsets ppbRowPointers = new png_bytep[height]; for (int i = 0; i < height; i++) ppbRowPointers[i] = pixels + i * rowSize; // now we can go ahead and just read the whole image png_read_image(png_ptr, ppbRowPointers); // read the additional chunks in the PNG file (not really needed) png_read_end(png_ptr, NULL); delete ppbRowPointers; if (iColorType == PNG_COLOR_TYPE_PALETTE){ png_colorp palette; int num_palette; png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); unsigned char *newPixels = new unsigned char[width * height * 3]; if (iBitDepth == 4){ for (int i = 0; i < rowSize * height; i++){ unsigned int i0 = pixels[i] >> 4; unsigned int i1 = pixels[i] & 0xF; newPixels[6 * i ] = palette[i0].red; newPixels[6 * i + 1] = palette[i0].green; newPixels[6 * i + 2] = palette[i0].blue; newPixels[6 * i + 3] = palette[i1].red; newPixels[6 * i + 4] = palette[i1].green; newPixels[6 * i + 5] = palette[i1].blue; } } else { for (int i = 0; i < rowSize * height; i++){ newPixels[3 * i ] = palette[pixels[i]].red; newPixels[3 * i + 1] = palette[pixels[i]].green; newPixels[3 * i + 2] = palette[pixels[i]].blue; } } format = FORMAT_RGB8; delete pixels; pixels = newPixels; } // and we're done png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(file); return true; }

Är du inte intresserad av stöd för paletterade png eller gråskala osv så går det att kapa ner lite.

Permalänk
Medlem

Eller gör det själv. Lite spännande men tar tid.

PNG Specification: http://www.w3.org/TR/REC-png-multi.html
ZLib Compress Data Format Specification (RFC1950): http://www.faqs.org/rfcs/rfc1950.html
Deflate Compression Specification (RFC1951): http://www.faqs.org/rfcs/rfc1951.html

Totalt blir det ca 1200 rader kod för att få till det. 900 för deflate och sedan runt 200-300 för png. Eller kör libpng.. vilket som.. beror på vad man känner för.

Visa signatur

Teeworlds - För dig som gillar gulliga saker med stora vapen.