Answered by:
Help! Questions about loading pictures with transparent info.

Question
-
pls see the attached picture.
image1 is the case that reading the file stream and then load it to the image control.
image2 is the case that reading the image's pixels after loading file, and then using the pixels to render the image.
image3 is the cation that base on case2, i changed the alpha info of the pixels,the rgb value is 0,0,0 and then render the image.
Question:
1. image1 and image2 were same pictures, i want to know why image1 could have transparent effect but iamge3 doesn't.
2. look at image2 and image3, both of them are load by Pixels and alpha property is 0, why the RGB value is 0,0,0 could present the transparent effect while RGB value is 255,255,255 couldn't.
My codes has labled below.
StorageFile file = await openPicker.PickSingleFileAsync(); if (file != null) { using (IRandomAccessStream filestream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) { BitmapDecoder decoder = await BitmapDecoder.CreateAsync(filestream); WriteableBitmap wbmp1 = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight); wbmp1.SetSource(filestream); image1.Source = wbmp1; } using (IRandomAccessStream filestream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) { BitmapDecoder decoder = await BitmapDecoder.CreateAsync(filestream); WriteableBitmap wbmp2 = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight); WriteableBitmap wbmp3 = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight); BitmapTransform transform = new BitmapTransform(); PixelDataProvider pix = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage); byte[] pixels = pix.DetachPixelData(); using (Stream stream = wbmp2.PixelBuffer.AsStream()) { stream.Write(pixels, 0, pixels.Length); stream.Flush(); } image2.Source = wbmp2; byte[] pixelsForimage3 = (byte[])pixels.Clone(); for(int i = 0; i < pixelsForimage3.Length / 4; i++) { if(pixelsForimage3[i * 4 + 3] == 0) { pixelsForimage3[i * 4 + 0] = 0; pixelsForimage3[i * 4 + 1] = 0; pixelsForimage3[i * 4 + 2] = 0; } } using (Stream stream = wbmp3.PixelBuffer.AsStream()) { stream.Write(pixelsForimage3, 0, pixelsForimage3.Length); stream.Flush(); } image3.Source = wbmp3; } }
Looking forwards to your answers!
Thanks sincerely!
Monday, January 13, 2014 9:32 AM
Answers
-
Ok. Running with your picture I get the behavior I expect. I'm not sure why you are opposed to using BitmapAlphaMode.Premultipled, as that is the right thing to do here.
The problem you're having is that the WriteableBitmap expects its buffer to be premultipled, so when you send the straight data it's too late to apply the transparency. Your code to edit the pixels effectively premultiplies it and so they draw as transparent. The white aura around the wheel is where there is partial transparency which the pixelsForimage3 loop leaves unmultiplied.
--Rob
- Marked as answer by Anne Jing Tuesday, January 21, 2014 6:44 AM
Thursday, January 16, 2014 1:30 AMModerator
All replies
-
I suspect the difference between one and 2/3 is that BitmapAlphaMode.Straight is incorrect for that image. Try premultiplied.
The difference between 2 and 3 is that the edge of the tire is probably partially transparent, bad the code discards only fully transparent pixels.
--Rob
Monday, January 13, 2014 4:19 PMModerator -
I suspect the difference between one and 2/3 is that BitmapAlphaMode.Straight is incorrect for that image. Try premultiplied.
The difference between 2 and 3 is that the edge of the tire is probably partially transparent, bad the code discards only fully transparent pixels.
--Rob
Now, the question is that if the premultilied parameter was used,the pixels obtained wasn't the original pixels any longer, so i can't use the premultiplied parameter.
I don't think you get fully aware of my question. Pls pay attention to my question No.2, the only difference between the two pictures was the RGB value. Both of them have the same Alpha value 0.
Looking foward your answer. thanks sincerely.
Tuesday, January 14, 2014 3:46 AM -
Hi Walker,
I understand your question, but you haven't provided enough information to do more than guess at an answer.
If you can share the image you are using then we can provide answers based on data rather than guesses.
--Rob
Tuesday, January 14, 2014 9:02 PMModerator -
quite right, attachment is the original image that i use.
Thanks sincerely.
Wednesday, January 15, 2014 6:21 AM -
Ok. Running with your picture I get the behavior I expect. I'm not sure why you are opposed to using BitmapAlphaMode.Premultipled, as that is the right thing to do here.
The problem you're having is that the WriteableBitmap expects its buffer to be premultipled, so when you send the straight data it's too late to apply the transparency. Your code to edit the pixels effectively premultiplies it and so they draw as transparent. The white aura around the wheel is where there is partial transparency which the pixelsForimage3 loop leaves unmultiplied.
--Rob
- Marked as answer by Anne Jing Tuesday, January 21, 2014 6:44 AM
Thursday, January 16, 2014 1:30 AMModerator -
I got what you said! Thanks sincerely, i’ll try to revise this problem by using what you suggested.
Thanks a lot Rob!
Friday, January 24, 2014 9:22 AM