PC Review


Reply
Thread Tools Rate Thread

creating a .bmp file

 
 
colin
Guest
Posts: n/a
 
      17th Nov 2007
Hi,
I have all the components of a .bmp file in memory wich i need
to write to a .bmp file, (or other convenient image file)
ie i have 256 color pallete of RGBquads and array of 8bit pixels,

I can create a System.Drawing.Bitmap and it allows me to set the
witdh,height,bpp, and even the pixel data,
but it doesnt seem to let me set the color palette,
the palette property field is read/write
but requires a System.Drawing.Imaging.ColorPalette
but there seems to be no way of creating one of these,

there must be a way surly am I missing something or do
I have to go and create the wheel all over again and
write my own BITMAPFILEHEADER,BITMAPINFOHEADER,etc
and write those to the file ?

Colin =^.^=


 
Reply With Quote
 
 
 
 
Peter Duniho
Guest
Posts: n/a
 
      18th Nov 2007
On 2007-11-17 15:29:53 -0800, "colin" <(E-Mail Removed)> said:

> I have all the components of a .bmp file in memory wich i need
> to write to a .bmp file, (or other convenient image file)
> ie i have 256 color pallete of RGBquads and array of 8bit pixels,
>
> I can create a System.Drawing.Bitmap and it allows me to set the
> witdh,height,bpp, and even the pixel data,
> but it doesnt seem to let me set the color palette,
> the palette property field is read/write
> but requires a System.Drawing.Imaging.ColorPalette
> but there seems to be no way of creating one of these,


I admit, I don't have any real experience using indexed color formats
in .NET. I do find it surprising that there's no good way to create a
palette.

However, the Microsoft knowledge base includes this suggestion to
create a dummy bitmap and grab the palette from that before disposing
the dummy bitmap:
http://support.microsoft.com/kb/319061

Also, it seems to me that if you've created an indexed-format Bitmap
instance, you should be able to just modify the palette that is created
with that instance, rather than replacing it altogether.

I would try the latter first.

And barring either of those methods working out for you, it's not like
it's really all that difficult to write the BMP file from scratch, even
if it is annoying.

Pete

 
Reply With Quote
 
colin
Guest
Posts: n/a
 
      18th Nov 2007
"Peter Duniho" <(E-Mail Removed)> wrote in message
news:200711171605488930-NpOeStPeAdM@NnOwSlPiAnMkcom...
> On 2007-11-17 15:29:53 -0800, "colin" <(E-Mail Removed)>
> said:
>
>> I have all the components of a .bmp file in memory wich i need
>> to write to a .bmp file, (or other convenient image file)
>> ie i have 256 color pallete of RGBquads and array of 8bit pixels,
>>
>> I can create a System.Drawing.Bitmap and it allows me to set the
>> witdh,height,bpp, and even the pixel data,
>> but it doesnt seem to let me set the color palette,
>> the palette property field is read/write
>> but requires a System.Drawing.Imaging.ColorPalette
>> but there seems to be no way of creating one of these,

>
> I admit, I don't have any real experience using indexed color formats in
> .NET. I do find it surprising that there's no good way to create a
> palette.
>
> However, the Microsoft knowledge base includes this suggestion to create a
> dummy bitmap and grab the palette from that before disposing the dummy
> bitmap:
> http://support.microsoft.com/kb/319061
>
> Also, it seems to me that if you've created an indexed-format Bitmap
> instance, you should be able to just modify the palette that is created
> with that instance, rather than replacing it altogether.
>
> I would try the latter first.
>
> And barring either of those methods working out for you, it's not like
> it's really all that difficult to write the BMP file from scratch, even if
> it is annoying.
>
> Pete


thanks, well I dont actually have an instance of a BMP image to start with,
but I do have the individual components wich are extracted from a texture
file, where one palette is shared by more than one pixel array.

I simply wish to put each image into a more easily displayed format.

il prob do the write the data to file directly,
seems a fag just becuase you cant actually create a palette.

Colin =^.^=


 
Reply With Quote
 
Michael Phillips, Jr.
Guest
Posts: n/a
 
      18th Nov 2007
> there must be a way surly am I missing something or do
> I have to go and create the wheel all over again and
> write my own BITMAPFILEHEADER,BITMAPINFOHEADER,etc
> and write those to the file ?


The easiest and most efficient way is the create a MemoryStream object and
write to it in this order:
1) Write the BITMAPFILEHEADER to the stream.
2) Write the BITMAPINFOHEADER to the stream.
3) Write the color palette to the stream.
4) Write the pixels to the stream.
5) Rewind the stream to position 0.
6) Create your Bitmap with System.Drawing.Bitmap using the stream
constructor.

Streams are extremely efficient as the BITMAP decoder reads the signature
first and only creates memory for its internal structures when the bitmap's
bits are actually accessed.



"colin" <(E-Mail Removed)> wrote in message
news:RPK%i.57331$(E-Mail Removed)...
> Hi,
> I have all the components of a .bmp file in memory wich i need
> to write to a .bmp file, (or other convenient image file)
> ie i have 256 color pallete of RGBquads and array of 8bit pixels,
>
> I can create a System.Drawing.Bitmap and it allows me to set the
> witdh,height,bpp, and even the pixel data,
> but it doesnt seem to let me set the color palette,
> the palette property field is read/write
> but requires a System.Drawing.Imaging.ColorPalette
> but there seems to be no way of creating one of these,
>
> there must be a way surly am I missing something or do
> I have to go and create the wheel all over again and
> write my own BITMAPFILEHEADER,BITMAPINFOHEADER,etc
> and write those to the file ?
>
> Colin =^.^=
>
>



 
Reply With Quote
 
Peter Duniho
Guest
Posts: n/a
 
      18th Nov 2007
On 2007-11-17 16:32:24 -0800, "colin" <(E-Mail Removed)> said:

> thanks, well I dont actually have an instance of a BMP image to start with,
> but I do have the individual components wich are extracted from a texture
> file, where one palette is shared by more than one pixel array.


Well, how did you expect to get the raw pixel data into a Bitmap instance?

Presumably you would be using LockBits. But LockBits requires a Bitmap
instance to be created in the first place.

So, presumably you were going to create a Bitmap instance, use LockBits
to set the pixel data for the image, and apply a palette to that
Bitmap. Well, just create the correct Bitmap format in the first
place, get the palette from the Palette property and modify that
palette directly.

> I simply wish to put each image into a more easily displayed format.


And so you can.

> il prob do the write the data to file directly,
> seems a fag just becuase you cant actually create a palette.


I don't understand that comment. I just described TWO different ways
to "create a palette" (or at least to get one you can set
appropriately).

I can understand you deciding you'd rather not bother with those
alternatives. But don't say it can't be done. Obviously it can, at
least according to the documentation.

Is there something about the methods I described that don't work as advertised?

Pete

 
Reply With Quote
 
colin
Guest
Posts: n/a
 
      18th Nov 2007

"Peter Duniho" <(E-Mail Removed)> wrote in message
news:2007111716553727544-NpOeStPeAdM@NnOwSlPiAnMkcom...
> On 2007-11-17 16:32:24 -0800, "colin" <(E-Mail Removed)>
> said:
>
>> thanks, well I dont actually have an instance of a BMP image to start
>> with,
>> but I do have the individual components wich are extracted from a texture
>> file, where one palette is shared by more than one pixel array.

>
> Well, how did you expect to get the raw pixel data into a Bitmap instance?


with the Bitmap constructor, it allows you to provide all but the palette...

IntPtr
scan=Marshal.UnsafeAddrOfPinnedArrayElement(mip.DataArray.ToArray(),0);
Bitmap bmp = new Bitmap(mip.USize, mip.VSize, ((mip.USize+3)/4)*4,
PixelFormat.Format8bppIndexed, scan);

> Presumably you would be using LockBits. But LockBits requires a Bitmap
> instance to be created in the first place.
>
> So, presumably you were going to create a Bitmap instance, use LockBits to
> set the pixel data for the image, and apply a palette to that Bitmap.
> Well, just create the correct Bitmap format in the first place, get the
> palette from the Palette property and modify that palette directly.
>
>> I simply wish to put each image into a more easily displayed format.

>
> And so you can.
>
>> il prob do the write the data to file directly,
>> seems a fag just becuase you cant actually create a palette.

>
> I don't understand that comment. I just described TWO different ways to
> "create a palette" (or at least to get one you can set appropriately).


I re read the link to the gif file, and saw the answer,
it was rather long and didnt seem to apply,
it seemed quicker to do it the dirty way,
however this didnt work and rather than spend ages debuging i re read what
you wrote a few times.

I failed to see how to actually modify the palette before re-reading a few
times lol.
for (x = 0; x < 256; x++)
{
bmp.Palette.Entries[x] = Color.FromArgb(palette[x].R, palette[x].G,
palette[x].B);
}
thanks it works now, although i think ive got my rows/cols messed up somehow
as it looks odd
but im kinda guesing at the format ive got.

Colin =^.^=


 
Reply With Quote
 
Peter Duniho
Guest
Posts: n/a
 
      18th Nov 2007
On 2007-11-17 17:44:09 -0800, "colin" <(E-Mail Removed)> said:

> [...]
> thanks it works now, although i think ive got my rows/cols messed up somehow
> as it looks odd
> but im kinda guesing at the format ive got.


Glad to hear that you were able to figure out what I meant.

As far as how it looks, I would guess you've got something wrong with
the stride somehow (that usually being the issue when someone says
their bitmap "looks odd" ), but it's hard to say for sure without
having all the information.

Pete

 
Reply With Quote
 
colin
Guest
Posts: n/a
 
      18th Nov 2007
This is the coode I have so far ...

IntPtr scan =
Marshal.UnsafeAddrOfPinnedArrayElement(mip.DataArray.ToArray(), 0);
Bitmap bmp = new Bitmap(mip.VSize, mip.USize, mip.VSize ,
PixelFormat.Format8bppIndexed, scan);
int x;
//System.Drawing.Imaging.ColorPalette pal = bmp.Palette;
for (x = 0; x < 256; x++)
{
FColor c = palette.Colors[x];
bmp.Palette.Entries[x] = System.Drawing.Color.FromArgb(c.R, c.G, c.B);
}
bmp.Save(filename + i.ToString() + ".bmp");


However the file seems to be saved in .png format,
256x256 8bpp file is only 22k insterad of at least 65k.
but my data isnt compressed,
wich is probably why its looking weird lol.

how can i specify/force it to use .BMP type format rather than png ?

Colin =^.^=


 
Reply With Quote
 
colin
Guest
Posts: n/a
 
      18th Nov 2007

"Michael Phillips, Jr." <(E-Mail Removed)0m> wrote in message
news:(E-Mail Removed)...
>> there must be a way surly am I missing something or do
>> I have to go and create the wheel all over again and
>> write my own BITMAPFILEHEADER,BITMAPINFOHEADER,etc
>> and write those to the file ?

>
> The easiest and most efficient way is the create a MemoryStream object
> and write to it in this order:
> 1) Write the BITMAPFILEHEADER to the stream.
> 2) Write the BITMAPINFOHEADER to the stream.
> 3) Write the color palette to the stream.
> 4) Write the pixels to the stream.
> 5) Rewind the stream to position 0.
> 6) Create your Bitmap with System.Drawing.Bitmap using the stream
> constructor.
>
> Streams are extremely efficient as the BITMAP decoder reads the signature
> first and only creates memory for its internal structures when the
> bitmap's bits are actually accessed.


hi thanks,
once ive done that Ive basicaly created a bmp file from scratch,
I only want to make a file copy anyway,
I had the folowing code but it didnt work and I havnt managed to figure out
why yet,
windows viewer just complains it cant display it
the various numbers was taken from
http://www.fortunecity.com/skyscrape.../bmpffrmt.html

BinaryWriter writer=new BinaryWriter(file);
writer.Write((UInt16)19778);
writer.Write((UInt32)1078 + mip.USize * mip.VSize);
writer.Write((UInt32)0);
writer.Write((UInt32)1078);
writer.Write((UInt32)40);
writer.Write((UInt32)mip.USize);
writer.Write((UInt32)mip.VSize);
writer.Write((UInt16)1);
writer.Write((UInt16)8);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
writer.Write((UInt32)0);
int x;
for (x = 0; x < 256; x++)
{
writer.Write(palette.Colors[x].B);
writer.Write(palette.Colors[x].G);
writer.Write(palette.Colors[x].R);
writer.Write((Byte)0);
}
for (x = 0; x < mip.USize * mip.VSize;x++ )
{
writer.Write(mip.DataArray[x]);
}

Colin =^.^=


 
Reply With Quote
 
Peter Duniho
Guest
Posts: n/a
 
      18th Nov 2007
On 2007-11-17 18:22:53 -0800, "colin" <(E-Mail Removed)> said:

> [...]
> However the file seems to be saved in .png format,
> 256x256 8bpp file is only 22k insterad of at least 65k.
> but my data isnt compressed,
> wich is probably why its looking weird lol.


Probably not. You can tell for sure by displaying the bitmap before
you save it (which is trivial to do in .NET), but the act of
compressing a bitmap for saving as PNG wouldn't normally change how the
image looks, since decompressing it again to turn it back into a Bitmap
instance would just reverse the original compression.

> how can i specify/force it to use .BMP type format rather than png ?


You have to specify a codec in the call to Save(). PNG is the default
that's used when you use a Save() overload that doesn't include an
ImageCodecInfo parameter.

I don't know if there's a better way, but the MSDN samples say that you
have to use ImageCodecInfo.GetImageEncoders() to get an array of
encoders, and then enumerate them to look for the format you want
(checking the MimeType property), using the encoder with that format.

This is the method I use in my programs and it works fine.

Pete

 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Creating Excel file that points to relative path .cub file NewUser1 Microsoft Excel Programming 0 11th Jan 2008 03:59 PM
Creating a batch file or executable file that will change drive le =?Utf-8?B?VHJhY3kgUC4=?= Windows XP Accessibility 0 16th Jun 2005 11:16 PM
Creating an import spec file from a file layout document =?Utf-8?B?ZGJhbGw=?= Microsoft Access External Data 1 26th May 2005 11:17 PM
creating an exe file with visual basic (installation file for Macros and Userforms) mibispam@gmx.de Microsoft Excel Programming 3 5th Aug 2004 10:16 AM
Creating a batch file to append date to file names bladeraptor Microsoft Windows 2000 CMD Promt 13 5th Feb 2004 03:56 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 05:53 AM.