从图像中清除元数据的简便方法?

时间:2014-02-05 19:30:23

标签: c# asp.net image-processing metadata system.drawing

我正在处理一个处理图像处理的公司项目的服务,其中一个方法应该从传递给它的图像中清除元数据。

认为实现我目前有工作,但我不确定它是否会影响图像的质量,或者是否有更好的方法来处理此任务。如果你知道更好的方法,你可以告诉我吗?

以下是有问题的方法:

public byte[] CleanMetadata(byte[] data)
{
    Image image;

    if (tryGetImageFromBytes(data, out image))
    {
        Bitmap bitmap = new Bitmap(image);

        using (var graphics = Graphics.FromImage(bitmap))
        {
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.CompositingMode = CompositingMode.SourceCopy;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            graphics.DrawImage(image, new Point(0, 0));
        }

        ImageConverter converter = new ImageConverter();

        return (byte[])converter.ConvertTo(image, typeof(byte[]));
    }

    return null;
}

并且,作为参考,tryGetImageFromBytes方法:

private bool tryGetImageFromBytes(byte[] data, out Image image)
{
    try
    {
        using (var ms = new MemoryStream(data))
        {
            image = Image.FromStream(ms);
        }
    }
    catch (ArgumentException)
    {
        image = null;

        return false;
    }

    return true;
}

重申:有没有更好的方法从图像中删除不涉及重绘它的元数据?

提前致谢。

2 个答案:

答案 0 :(得分:3)

  

元数据 - 获取或设置与此关联的元数据   编码期间的位图。

  • '哎呀,我(不是偶然)忘记了某种方式:将原始位图文件打开到System.drawing.Bitmap对象中。 Clone它是一个新的Bitmap对象。将克隆的内容写入新文件。像这样的单行:

    ((System.Drawing.Bitmap)System.Drawing.Image.FromFile(@ “C:\ file.png”)克隆()。)保存。(@ “C:\文件nometa.png”);

  • 直接文件操作方式(仅适用于JPEG):Blog post about removing the EXIF area

答案 1 :(得分:1)

我建议这样做,来源就在这里:Removing Exif-Data for jpg file

改变第一个功能

public Stream PatchAwayExif(Stream inStream)
{
  Stream outStream = new MemoryStream();
  byte[] jpegHeader = new byte[2];
  jpegHeader[0] = (byte)inStream.ReadByte();
  jpegHeader[1] = (byte)inStream.ReadByte();
  if (jpegHeader[0] == 0xff && jpegHeader[1] == 0xd8) //check if it's a jpeg          file
  {
     SkipAppHeaderSection(inStream);
  }
  outStream.WriteByte(0xff);
  outStream.WriteByte(0xd8);

  int readCount;
  byte[] readBuffer = new byte[4096];
  while ((readCount = inStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
  outStream.Write(readBuffer, 0, readCount);

  return outStream;
}

第二个没有变化的功能,如帖子

    private void SkipAppHeaderSection(Stream inStream)
    {
        byte[] header = new byte[2];
        header[0] = (byte)inStream.ReadByte();
        header[1] = (byte)inStream.ReadByte();

        while (header[0] == 0xff && (header[1] >= 0xe0 && header[1] <= 0xef))
        {
            int exifLength = inStream.ReadByte();
            exifLength = exifLength << 8;
            exifLength |= inStream.ReadByte();

            for (int i = 0; i < exifLength - 2; i++)
            {
                inStream.ReadByte();
            }
            header[0] = (byte)inStream.ReadByte();
            header[1] = (byte)inStream.ReadByte();
        }
        inStream.Position -= 2; //skip back two bytes
    }