none
.jpg图片包含PhotoOrientation信息时该如何使用BitmapDecoder来正确解码图片?? RRS feed

  • 问题

  • 这是正常打开的图片,使用Lumia 950拍摄,PhotoOrientation属性为PhotoOrientation.Rotate270.

    http://pan.baidu.com/s/1geNmeQ3 百度网盘测试图片链接

    这是我使用BitmapDecoder 解码的图片,图片的比例和方向都是错误的,

    下面是解码的code

            private async Task<WriteableBitmap> ScalePicture(int controlHeight, int controlWidth, 
                ImageProperties imgProperties,InMemoryRandomAccessStream memoryStream)
            {
                if (memoryStream == null)
                    goto Exit0;

                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(memoryStream);

                uint scaleHeight, scaleWidth = 0;

                if (controlHeight > imgProperties.Height)
                {
                    scaleHeight = imgProperties.Height;
                    scaleWidth = imgProperties.Width;
                }
                else
                {
                    scaleHeight = (uint)controlHeight;
                    scaleWidth = imgProperties.Width * (uint)controlHeight / imgProperties.Height;
                }

                BitmapTransform transform = new BitmapTransform();
                BitmapBounds bounds = new BitmapBounds();
                bounds.X = 0;
                bounds.Y = 0;
                bounds.Height = scaleHeight;
                bounds.Width = scaleWidth;

                transform.Bounds = bounds;
                transform.ScaledHeight = scaleHeight;
                transform.ScaledWidth = scaleWidth;
                transform.InterpolationMode = BitmapInterpolationMode.Fant;

                PixelDataProvider pix = await decoder.GetPixelDataAsync(
                    decoder.BitmapPixelFormat,
                    decoder.BitmapAlphaMode,
                    transform,
                    ExifOrientationMode.IgnoreExifOrientation,
                    ColorManagementMode.ColorManageToSRgb);

                byte[] pixels = pix.DetachPixelData();

                WriteableBitmap Bmp = new WriteableBitmap((int)scaleWidth, (int)scaleHeight);

                using (Stream pixStream = Bmp.PixelBuffer.AsStream())
                {
                    await pixStream.WriteAsync(pixels, 0, (int)scaleWidth * (int)scaleHeight * 4);
                    await pixStream.FlushAsync();
                    pixStream.Seek(0,SeekOrigin.Begin);

                    Bmp.Invalidate();

                    return Bmp;
                }

                Exit0:
                return null;
            }

    如果照片的PhotoOrientation属性为PhotoOrientation.Normal使用BitmapDecoder解码出的图片比例和方向就是正常的.像这种情况不知道该如何解决?


    2017年5月21日 3:01

答案

全部回复

  • 你好,我使用过ExifOrientationMode.RespectExifOrientation属性,然而这会引发异常,值不在预期的范围内
    2017年5月21日 12:05
  • 我按照你说的修改了代码,不知道是不是我哪里修改的不对? 在运行的时候依然会出现异常 请你帮我看一下问题出在哪里好吗

            private async Task<WriteableBitmap> ScalePicture(int controlHeight, int controlWidth, 
                 ImageProperties imgProperties,InMemoryRandomAccessStream memoryStream)
            {
                if (memoryStream == null)
                    goto Exit0;

                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(memoryStream);

                uint scaleHeight, scaleWidth = 0;
                uint imgHeight, imgWidth = 0;
                bool isExChange = false;

                //test code
                if (decoder.OrientedPixelHeight == imgProperties.Height && 
                    decoder.OrientedPixelWidth == imgProperties.Width)
                {
                    //无需缩放调整
                    imgHeight = imgProperties.Height;
                    imgWidth = imgProperties.Width;
                }
                else
                {
                    imgHeight = imgProperties.Width;
                    imgWidth = imgProperties.Height;
                    isExChange = true;
                }
                //test code

                //计算绽放之后的图片size
                if (controlHeight > imgProperties.Height)
                {
                    //scaleHeight = imgProperties.Height;
                    //scaleWidth = imgProperties.Width;
                    scaleHeight = imgHeight;
                    scaleWidth = imgWidth;
                }
                else
                {
                    //scaleHeight = (uint)controlHeight;
                    //scaleWidth = imgProperties.Width * (uint)controlHeight / imgProperties.Height;
                    scaleHeight = (uint)controlHeight;
                    scaleWidth = imgWidth * (uint)controlHeight / imgHeight;
                }

                BitmapTransform transform = new BitmapTransform();
                BitmapBounds bounds = new BitmapBounds();
                bounds.X = bounds.Y = 0;
                bounds.Height = scaleHeight;
                bounds.Width = scaleWidth;

                transform.Bounds = bounds;
                transform.ScaledHeight = scaleHeight;
                transform.ScaledWidth = scaleWidth;
                transform.InterpolationMode = BitmapInterpolationMode.Fant;

                PixelDataProvider pix = await decoder.GetPixelDataAsync(
                    decoder.BitmapPixelFormat,
                    decoder.BitmapAlphaMode,
                    transform,
                    ExifOrientationMode.RespectExifOrientation,
                    ColorManagementMode.ColorManageToSRgb);

                byte[] pixels = pix.DetachPixelData();

                //WriteableBitmap Bmp = new WriteableBitmap((int)scaleWidth, (int)scaleHeight);
                WriteableBitmap Bmp;
                if(isExChange)
                {
                    Bmp = new WriteableBitmap((int)scaleHeight, (int)scaleWidth);
                }
                else
                {
                    Bmp = new WriteableBitmap((int)scaleWidth, (int)scaleHeight);
                }

                using (Stream pixStream = Bmp.PixelBuffer.AsStream())
                {
                    await pixStream.WriteAsync(pixels, 0, (int)scaleWidth * (int)scaleHeight * 4);
                    await pixStream.FlushAsync();
                    pixStream.Seek(0,SeekOrigin.Begin);

                    Bmp.Invalidate();

                    return Bmp;
                }

                Exit0:
                return null;
            }

                            
    2017年5月22日 2:04
  • ?????
    • 已标记为答案 花開灬 2017年5月22日 11:30
    • 已编辑 [-] 2018年1月11日 11:45
    2017年5月22日 9:47
  • 用了上面的代码图片可以正常显示了, 非常感谢!!!
    2017年5月22日 11:30