why are pixels altered when i construct a bitmap from memory stream?

M

margec3

when i reconstruct the bitmap from the byte array (memory stream) sent
by the server, i realized the pixels are not exactly the same as the
ones sent from the server, which matters to me because i am doing
image steganography, and i am hiding encrypted data in the R component
of some pixels. i wonder if the compact framework Bitmap class is
doing some quiet conversion, can someone shed some light about this
and it will be even more helpful, if someone can tell me how i can
recover the exact bitmap sent by the server?

thanks a lot!

======================= details

// at server, bitmapStream is a MemoryStream that i put together by
converting a gif file from indexed pixel format to raw (A)RBG format
Bitmap carrierBitmap = new Bitmap(bitmapStream);

// store encrypted data at the 'R' element of pixels at various
positions of carrierBitmap (i am doing image steganography)

// save the worked up bitmap back to memory stream
bitmapStream.Flush();
carrierBitmap.Save(bitmapStream,
System.Drawing.Imaging.ImageFormat.Png);

//******* examine pixels of the first 10 worked up positions of the
result bitmap (to be compared with the one recovered by the client
later)

// convert memory stream to byte array
byte[] embeddedBuf = bitmapStream.ToArray();

// send byte array to pocket PC client

// recover the memory stream at client

Bitmap carrierBitmap = new Bitmap(bitmapStream);

//******* examine pixels of the first 10 positions of the recovered
bitmap, and they're different, not just the R value that i need to
recover the original data with, but G and B too!!

=======================

this is how i converted an image in indexed pixel format (gif file) to
raw (A)RBG format:

public static MemoryStream convertBitmap(string fileName)
{
Bitmap myImage = new Bitmap(fileName);

int imageSize = myImage.Width * myImage.Height;
MemoryStream ms = new MemoryStream(imageSize);
myImage.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);

Bitmap resultImage = new Bitmap(myImage.Width,
myImage.Height);
Graphics resultG = Graphics.FromImage(resultImage);
resultG.DrawImage(myImage, 0, 0);

ms.Flush();
resultImage.Save(ms,
System.Drawing.Imaging.ImageFormat.Png);

return ms;
}

===========
 
G

Guest

it's likely a conversion for 555 or 565 - the display driver for the device
probably doesn't support the color depth of the image in the stream, so it
approximates some of the colors.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded World
www.OpenNETCF.com
 
M

margec3

thanks for the feedback Chris!! i was only running the client on a
pocket pc 2003
emulator, is there any way to by-pass this conversion?

thanks again.

it's likely a conversion for 555 or 565 - the display driver for the device
probably doesn't support the color depth of the image in the stream, so it
approximates some of the colors.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded Worldwww.OpenNETCF.com


when i reconstruct thebitmapfrom the byte array (memory stream) sent
by the server, i realized the pixels are not exactly the same as the
ones sent from the server, which matters to me because i am doing
image steganography, and i am hiding encrypted data in the R component
of some pixels. i wonder if the compact frameworkBitmapclass is
doing some quiet conversion, can someone shed some light about this
and it will be even more helpful, if someone can tell me how i can
recover the exactbitmapsent by the server?
thanks a lot!
======================= details
// at server, bitmapStream is a MemoryStream that i put together by
converting a gif file from indexed pixel format to raw (A)RBG format
BitmapcarrierBitmap = newBitmap(bitmapStream);
// store encrypted data at the 'R' element of pixels at various
positions of carrierBitmap (i am doing image steganography)
// save the worked upbitmapback to memory stream
bitmapStream.Flush();
carrierBitmap.Save(bitmapStream,
System.Drawing.Imaging.ImageFormat.Png);
//******* examine pixels of the first 10 worked up positions of the
resultbitmap(to be compared with the one recovered by the client
later)
// convert memory stream to byte array
byte[] embeddedBuf = bitmapStream.ToArray();
// send byte array to pocket PC client
// recover the memory stream at client
BitmapcarrierBitmap = newBitmap(bitmapStream);
//******* examine pixels of the first 10 positions of the recovered
bitmap, and they're different, not just the R value that i need to
recover the original data with, but G and B too!!

this is how i converted an image in indexed pixel format (gif file) to
raw (A)RBG format:
public static MemoryStream convertBitmap(string fileName)
{
BitmapmyImage = newBitmap(fileName);
int imageSize = myImage.Width * myImage.Height;
MemoryStream ms = new MemoryStream(imageSize);
myImage.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
BitmapresultImage = newBitmap(myImage.Width,
myImage.Height);
Graphics resultG = Graphics.FromImage(resultImage);
resultG.DrawImage(myImage, 0, 0);

return ms;
}
===========
 
G

Guest

You need to use a DIB, not a DDB. I believe the CF team blogged on what
ctors of the Bitmap class create which type.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded World
www.OpenNETCF.com


margec3 said:
thanks for the feedback Chris!! i was only running the client on a
pocket pc 2003
emulator, is there any way to by-pass this conversion?

thanks again.

it's likely a conversion for 555 or 565 - the display driver for the
device
probably doesn't support the color depth of the image in the stream, so
it
approximates some of the colors.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded Worldwww.OpenNETCF.com


when i reconstruct thebitmapfrom the byte array (memory stream) sent
by the server, i realized the pixels are not exactly the same as the
ones sent from the server, which matters to me because i am doing
image steganography, and i am hiding encrypted data in the R component
of some pixels. i wonder if the compact frameworkBitmapclass is
doing some quiet conversion, can someone shed some light about this
and it will be even more helpful, if someone can tell me how i can
recover the exactbitmapsent by the server?
thanks a lot!
======================= details
// at server, bitmapStream is a MemoryStream that i put together by
converting a gif file from indexed pixel format to raw (A)RBG format
BitmapcarrierBitmap = newBitmap(bitmapStream);
// store encrypted data at the 'R' element of pixels at various
positions of carrierBitmap (i am doing image steganography)
// save the worked upbitmapback to memory stream
bitmapStream.Flush();
carrierBitmap.Save(bitmapStream,
System.Drawing.Imaging.ImageFormat.Png);
//******* examine pixels of the first 10 worked up positions of the
resultbitmap(to be compared with the one recovered by the client
later)
// convert memory stream to byte array
byte[] embeddedBuf = bitmapStream.ToArray();
// send byte array to pocket PC client
// recover the memory stream at client
BitmapcarrierBitmap = newBitmap(bitmapStream);
//******* examine pixels of the first 10 positions of the recovered
bitmap, and they're different, not just the R value that i need to
recover the original data with, but G and B too!!

this is how i converted an image in indexed pixel format (gif file) to
raw (A)RBG format:
public static MemoryStream convertBitmap(string fileName)
{
BitmapmyImage = newBitmap(fileName);
int imageSize = myImage.Width * myImage.Height;
MemoryStream ms = new MemoryStream(imageSize);
myImage.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
BitmapresultImage = newBitmap(myImage.Width,
myImage.Height);
Graphics resultG = Graphics.FromImage(resultImage);
resultG.DrawImage(myImage, 0, 0);

return ms;
}
===========
 
H

Hilton

Chris said:
You need to use a DIB, not a DDB. I believe the CF team blogged on what
ctors of the Bitmap class create which type.

....and CF team can guarantee us that the constructors will continue to use
these DIB/DDBs as specified? i.e. the ctors that use a DIB will foreever
use a DIB, and the ones that use a DDb will foreever use a DDB.

Hilton
 
G

Guest

To that I have no answer, but it's likely to be "no, that's no guaranteed".

Personally I think there should be two separate Bitmap class types - Device
Dependent and Device Independent, and they should encapsulate a DDB or a DIB
appropriately so we don't have to guess or look up which overload does what.
Even a property that we could set/get to tell/ask it what it's using would
be nice, but since they're following a philosophy of maintaining API
compatibility with the full framework, probably neither will happen.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded World
www.OpenNETCF.com
 
M

margec3

ok, i read up on 555, 565 conversion chris mentioned, and came up with
a work-around (or hack, or whatever you want to call it), by having
the server do the 8-bit to 5-bit conversion, send the bits which are
shifted off, peggy-backed those bits to the bitmap, and have the
client re-cover the original pixel value.

anyway, now my problem is solved, thanks people!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top