I'm building a pipeline component that can convert an image format to another format (say jpg to png for example):
using (System.Drawing.Bitmap bmpSource = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(msgReceived.BodyPart.Data))
{
VirtualStream strConvertedImage = new VirtualStream();
bmpSource.Save(strConvertedImage, System.Drawing.Imaging.ImageFormat.Png);
strConvertedImage.Flush();
strConvertedImage.Position = 0;
ctxPipeline.ResourceTracker.AddResource(strConvertedImage);
}
msgReceived.BodyPart.Data = strConvertedImage;
I use this component in a receive pipeline with a file adaptor, and it executes fine, but when I subscribe with a passthrough send port and file adaptor, the file written is only part of the actual image.
Note:
I can use this same code (with the exception of loading the source bitmap from a file stream instead a BizTalk message stream) in a windows console application and it works fine, so this seems BizTalk related.
I think it has something to do with the source stream.
It seems odd behavior, but if I inspect the length and position properties of msgReceived.BodyPart.Data, Length is 904678. Position is 0. Position stays at 0 and never changes even as the bitmap is loaded and saved. I would have expected that as I load the bitmap, the position changes, unless the BitMap.FromStream method seeks to the beginning of the stream once it's finished loading.
Also, When I save the bitmap to my new stream as a png, the new stream length is always 54789, representing only the first party of the image. Now if I immediately save the same bitmap object to a new stream again, it's size is then 1400868, representing the entire image and msgReceived.BodyPart.Data.Position is now 904678 indicating that the entire source stream has been read.
Here's an example:
using (System.Drawing.Bitmap bmpSource = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(msgReceived.BodyPart.Data))
{
VirtualStream strConvertedImage = new VirtualStream();
bmpSource.Save(strConvertedImage, System.Drawing.Imaging.ImageFormat.Png);
strConvertedImage.Flush();
strConvertedImage.Position = 0;
//msgReceived.BodyPart.Data.Position is 0
//msgReceived.BodyPart.Data.Length is 904678
//strConvertedImage.Position is 54789 (Only part of image was saved)
strConvertedImage = new VirtualStream();
bmpSource.Save(strConvertedImage, System.Drawing.Imaging.ImageFormat.Png);
//msgReceived.BodyPart.Data.Position is 904678
//msgReceived.BodyPart.Data.Length is 904678
//strConvertedImage.Position is 1400868 (full image was saved)
msgReceived.BodyPart.Data = strConvertedImage;
ctxPipeline.ResourceTracker.AddResource(strConvertedImage);
}
Why would the position of msgReceived.BodyPart.Data only advance on the second save? And why would the first save attempt only save part of the converted image. I'm baffled!