【问题标题】:Removing EXIF Does not work when using Different Encoders to Choose Format使用不同的编码器选择格式时删除 EXIF 不起作用
【发布时间】:2016-04-24 21:37:54
【问题描述】:

考虑到 EXIF 方向标签,我使用以下代码来修复图像的方向

 static void FixImageOrientation(Image srce)
        {
            const int ExifOrientationId = 0x112;
            // Read orientation tag
            if (!srce.PropertyIdList.Contains(ExifOrientationId)) return;
            var prop = srce.GetPropertyItem(ExifOrientationId);
            var orient = BitConverter.ToInt16(prop.Value, 0);
            // Force value to 1
            prop.Value = BitConverter.GetBytes((short)1);
            srce.SetPropertyItem(prop);

            // Rotate/flip image according to <orient>
            switch (orient)
            {
                case 1:
                 srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
                 break;

                case 2:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipX);
                    break;

                case 3:
                     srce.RotateFlip(RotateFlipType.Rotate180FlipNone);
                     break;

                case 4:
                    srce.RotateFlip( RotateFlipType.Rotate180FlipX);
                    break;

                case 5:
                     srce.RotateFlip(RotateFlipType.Rotate90FlipX);
                     break;

                case 6:
                    srce.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    break;

                case 7:
                    srce.RotateFlip(RotateFlipType.Rotate270FlipX);
                    break;

                case 8:
                     srce.RotateFlip(RotateFlipType.Rotate270FlipNone);
                     break;

                default:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
                    break;
            }
        }

此代码正确删除了 EXIF 方向标记。 保存图像作品是我简单地使用 img.save

但该应用程序为用户提供了选择图像格式的能力。为此,我使用以下代码

 private void saveJpeg(string path, Bitmap img, long quality)
        {


            EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);


            ImageCodecInfo Codec = this.getEncoderInfo(imgformat);

            if (Codec == null)
                return;

            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = qualityParam;

            img.Save(path + ext, Codec, encoderParams);
        }
        public string getimgext(string ccodec)
        {
            if (ccodec.Equals("image/png"))
            {
                return ".png";
            }
            else if (ccodec.Equals("image/jpeg"))
            {
                return ".jpg";
            }
            else if (ccodec.Equals("image/tiff"))
            {
                return ".tif";
            }
            else if (ccodec.Equals("image/bmp"))
            {
                return ".bmp";
            }

            else if (ccodec.Equals("image/gif"))
            {
                return ".gif";
            }
            else
            {
                return null;
            }

        }
        private ImageCodecInfo getEncoderInfo(string mimeType)
        {
            // Get image codecs for all image formats
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

            // Find the correct image codec
            for (int i = 0; i < codecs.Length; i++)
                if (codecs[i].MimeType == mimeType)
                    return codecs[i];
            return null;
        }

当我使用SaveJpeg 保存图像时,图像以错误的方向保存。我做错了什么?请帮忙。

更新:

我已经修改了方法,因此我不需要创建位图的新实例,因为循环处理许多文件。但是除非我创建位图的新实例,否则这不起作用。此过程额外消耗 10 + 与旧版本相比,处理时间的秒数。 我使用这样的代码

image = (Bitmap)FixImageOrientation(Bitmap.FromFile(path));


Image FixImageOrientation(Image srce)
        {
            const int ExifOrientationId = 0x112;
            // Read orientation tag
            if (!srce.PropertyIdList.Contains(ExifOrientationId)) return srce;
            var prop = srce.GetPropertyItem(ExifOrientationId);
            var orient = BitConverter.ToInt16(prop.Value, 0);
            // Force value to 1
            prop.Value = BitConverter.GetBytes((short)1);
            srce.SetPropertyItem(prop);

            // Rotate/flip image according to <orient>
            switch (orient)
            {
                case 1:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
                    return srce;
                    

                case 2:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipX);
                    return srce;

                case 3:
                    srce.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    return srce;

                case 4:
                    srce.RotateFlip(RotateFlipType.Rotate180FlipX);
                    return srce;

                case 5:
                    srce.RotateFlip(RotateFlipType.Rotate90FlipX);
                    return srce;

                case 6:
                    srce.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    return srce;

                case 7:
                    srce.RotateFlip(RotateFlipType.Rotate270FlipX);
                    return srce;

                case 8:
                    srce.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    return srce;

                default:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
                    return srce;
            }
        }

【问题讨论】:

  • saveJpeg 有一些编译错误,是否缺少一些代码?
  • 我还发现,如果用户在上传之前自己定位图像,有时结果仍然是错误的方向。这是由于某些成像程序(Microsoft Office 图片查看器)在重新定向后没有删除/更新 EXIF 标记。需要考虑的事情。

标签: c# .net bitmap exif system.drawing


【解决方案1】:

在一种方法中,您有Image 类型的参数,但在另一种方法中Bitmap。所以我猜测你在调用FixImageOrientation之前将源JPEG图像转换为位图。

这将起作用:

 var jpeg = Image.FromFile("original.jpg");
 FixImageOrientation(jpeg);
 var bitmap = new Bitmap(jpeg);
 saveJpeg("new",bitmap,1);

这不会:

var jpeg = Image.FromFile("original.jpg");
var bitmap = new Bitmap(jpeg);
FixImageOrientation(bitmap);
saveJpeg("new", bitmap, 1);

【讨论】:

  • 会尝试回来。谢谢
  • 非常感谢 :) 这确实是问题所在。我曾尝试修改 FixImageOrientation 代码以返回位图。它不起作用。请您修改方法,以便我可以阻止创建新对象,从而节省内存。
  • 不客气@techno。您可以发布无效的修改代码吗?据我所知,如果不创建 Bitmap 实例,您将无法将图像转换为位图。因此,为了节省内存,请确保在创建位图后处理源图像。
  • 我真的很忙..我会接受这个答案..请给我一些时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-05
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 2019-06-08
相关资源
最近更新 更多