我正在处理一个处理图像处理的公司项目的服务,其中一个方法应该从传递给它的图像中清除元数据。
我认为实现我目前有工作,但我不确定它是否会影响图像的质量,或者是否有更好的方法来处理此任务。如果你知道更好的方法,你可以告诉我吗?
以下是有问题的方法:
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;
}
重申:有没有更好的方法从图像中删除不涉及重绘它的元数据?
提前致谢。
答案 0 :(得分:3)
Metadata
集合。引用MSDN:元数据 - 获取或设置与此关联的元数据 编码期间的位图。
'哎呀,我(不是偶然)忘记了某种方式:将原始位图文件打开到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
}