使用MetaDataExtractor将EXIF添加回调整大小的图像

时间:2017-09-30 16:46:41

标签: .net exif metadata-extractor

使用MVC应用程序上传图像,我们需要在保存到数据库之前减小文件大小,但是想要保留EXIF数据...我能想到的唯一方法就是从原始版本中获取上传的图像,然后使用MetadataExtractor

将其添加到已调整大小的图像

我们可以像这样获取元数据

 Dim vMetadata As IEnumerable(Of System.IO.Directory) = MetadataExtractor.ImageMetadataReader.ReadMetadata(file.InputStream)

然后像这样重新调整图像

fext = IO.Path.GetExtension(file.FileName).ToLower
Dim vLen As Integer = file.ContentLength
Dim vData(vLen - 1) As Byte
Dim image_file As System.Drawing.Image = System.Drawing.Image.FromStream(file.InputStream)
Dim image_height As Integer = image_file.Height
Dim image_width As Integer = image_file.Width
Dim max_height As Integer = 240
Dim max_width As Integer = 320

image_height = (image_height * max_width) / image_width
image_width = max_width

If image_height > max_height Then
    image_width = (image_width * max_height) / image_height
    image_height = max_height
End If

Dim bitmap_file As New System.Drawing.Bitmap(image_file, image_width, image_height)

Using vStream As New IO.MemoryStream
    Select Case fext
        Case ".jpg"
            bitmap_file.Save(vStream, System.Drawing.Imaging.ImageFormat.Jpeg)
        Case ".jpeg"
            bitmap_file.Save(vStream, System.Drawing.Imaging.ImageFormat.Jpeg)
        Case ".png"
            bitmap_file.Save(vStream, System.Drawing.Imaging.ImageFormat.Png)
        Case ".gif"
            bitmap_file.Save(vStream, System.Drawing.Imaging.ImageFormat.Gif)
        Case Else
            bitmap_file.Save(vStream, System.Drawing.Imaging.ImageFormat.Jpeg)
    End Select
    vStream.Position = 0
    vStream.Read(vData, 0, vStream.Length)
    vImageFile = vData

    vData = Nothing
End Using

所以我们将元数据保存为Dictionary,并将缩小尺寸的图像文件作为我们现在可以保存的变量vImageFile ...

问题是 - 我们如何将元数据添加回新文件?

谢谢

-------------------编辑已添加2017年10月1日--------------------

我已添加此代码

Dim vOrientationNumber As Integer = 1

                    Dim vEXIF As String = ""
                    Dim vDirectories = ImageMetadataReader.ReadMetadata(file.InputStream)
                    Dim vSub = vDirectories.OfType(Of ExifSubIfdDirectory)().FirstOrDefault
                    If Not vSub Is Nothing Then
                        Dim vOrientationObj = vSub.GetObject(ExifDirectoryBase.TagOrientation)
                        If Not vOrientationObj Is Nothing Then
                            If Not vOrientationObj.Equals(DBNull.Value) Then
                                vOrientationNumber = Convert.ToInt16(vOrientationObj)
                            End If
                        End If
                    End If

                    For Each vDirectory In vDirectories
                        For Each Tag In vDirectory.Tags
                            vEXIF += vDirectory.Name & " " & Tag.Name & " " & Tag.Description & Environment.NewLine
                        Next
                    Next

获取Orientation数字的句柄,但变量vSub始终为Nothing。我知道这个图像的方向编号就在那里(因为它在主WPF桌面应用程序中找到并旋转它)。知道我现在做错了什么吗?

1 个答案:

答案 0 :(得分:1)

MetadataExtractor不支持向文件写入元数据。这是一个受欢迎的功能请求,但要正确地执行此操作(这显然是必要的,因为人们可能会覆盖他们的文件)需要一些工作。

但是,为了做到这一点,只要您处理JPEG文件,库就会提供一些可能有用的代码。

JPEG文件基本上是所谓的JPEG段列表。 Exif数据位于其中一个细分市场中。因此,如果您在原始图片中隔离该细分,则可以在调整其大小后将其替换。

不幸的是,我没有任何代码。您可以使用JpegSegmentReader来提取所需的片段(Exif在JpegSegmentType.App1中),这应该可以帮助您入门。

您看到的字符串值是 description 。要访问原始方向值,请使用以下代码:

var directories = ImageMetadataReader.ReadMetadata(imagePath);

var subIfd = directories.OfType<ExifIfd0Directory>().FirstOrDefault();

int? orientation = subIfd?.GetObject(ExifDirectoryBase.TagOrientation);

请注意,subIfdorientation都可以为空,具体取决于图片。

它是C#因为我不懂VB.NET,对不起。希望它能为您直接转换。