Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

How to read then write PNG Image data to another file


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
No replies to this topic

#1 kamal7   Members   -  Reputation: 107

Like
0Likes
Like

Posted 04 September 2012 - 07:43 PM

I have many spritesheets as .bmp image format located in memory within a .pak file. I write other information like rectangle cords for individual sprites, and bitmap header data all within one .pak file. I am currently working towards implementing .png image support; however I am having trouble. I will try to explain...

I render all the sprites within my game program using DirectX 9 with no problem, but when I try to render the .png images I get a Data Error returned value when I read the .png image memory. It is clear to me that the image is not read completely and the image header data is incorrect (i.e. image size/height/width). Here is how I write my image files into the .pak file using a seperate form app in C language:

fs = new FileStream(file, FileMode.Open, FileAccess.Read); //reads .pak file
BinaryReader br = new BinaryReader(fs); //.pak file as binary data

//...//some data read in between to get each sprite frame cords for each sprite in spritesheet

br.BaseStream.Seek(bitmapStart, SeekOrigin.Begin); //beginning of spritesheet/image header

BitmapFile BF = new BitmapFile();
BitmapFileHeader BFH = new BitmapFileHeader();

BFH.type = br.ReadUInt16();
BFH.size = br.ReadUInt32();
BFH.reserved1 = br.ReadUInt16();
BFH.reserved2 = br.ReadUInt16();
BFH.offBits = br.ReadUInt32();

BF.bmpHeader = BFH;
br.BaseStream.Seek(-14, SeekOrigin.Current); //pointer to beginning of spritesheet/image header (.bmp image has 14 byte header)
byte[] bitmapData = br.ReadBytes((int)BF.bmpHeader.size); //reads spritesheet/image data

return new Bitmap(new MemoryStream(bitmapData)); // spritesheet/image data returned and displayed

I read in multiple places that .PNG images have 8 byte headers, but I cannot find how it is structured.

PS: For some reason the program (Windows Form App) that writes the .pak files can read the .png images within the .pak files after it creates them and it can be displayed on the picture box within the form; however, on my main game written in C++ it cannot be rendered in DirectX 9 and returns invalid data. Unless the image written in the .pak file is a .bmp file, my game cannot render it because it cannot read the data.

Here is how I read the .pak file in my game application:

BITMAPFILEHEADER fileHeader;
BYTE *imageBuffer;

HANDLE hPakFile = CreateFile("Sprites\\Interface.pak", GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL); //opens .pak file

//...//some data read in between to get each sprite frame cords for each sprite in the spritesheet/image which is read correctly so I know the file isn't corrupt but how I write the image in the .pak file

SetFilePointer(hPakFile, m_dwBitmapFileStartLoc, NULL, FILE_BEGIN); //pointer to beginning of spritesheet/image header
ReadFile(hPakFile, (char *)&fileHeader, 14, &bytesRead, NULL); //reads header data (14 bytes)
imageBuffer = new BYTE[fileHeader.bfSize-14];
ReadFile(hPakFile, imageBuffer, fileHeader.bfSize-14, &bytesRead, NULL); //reads raw image data

D3DXCreateTextureFromFileInMemoryEx(device, imageBuffer, bytesRead, D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0, NULL, NULL, &texture); //sets image data to texture

When I try to read .png file data D3DXCreateTextureFromFileInMemoryEx returns an invalid data error and the image size, height, width, etc. is all wrong. When I read a .bmp image it works perfectly.

So obviously the way I am writing (within the form application that handles writing my .pak files) or reading (from my game application) the .png image data is incorrect. But I am curious as to why my form app still outputs the .png image data correctly after reading it from a .pak file that it wrote... and that my main game app written in c++ doesnt read it properly.

I know this may seem long to read but I hope that someone can guide my to a proper solution.

Thanks a lot I will appreciate any help very much!

I tried to be as straight to the point as possible, but if you guys need any more info please ask.

Edited by kamal7, 04 September 2012 - 07:45 PM.


Sponsor:



Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS