保留Exif /图像属性

时间:2016-01-19 16:50:13

标签: vb.net image image-processing

在网络应用中,用户可以上传保存在服务器上的图像。它使用以下代码在后端创建图像的缩略图,但图像的所有exif数据都将丢失。

我希望在整个过程中保留原始图像中的exif数据,并将其包含在最终流中。我可以从图像中读取exif属性,但在保存时不能保留它。

为了澄清,我不是在尝试阅读,解析或做任何特定于元数据本身的事情,我只是想在图像处理过程中保留原始图像中的内容。

Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

    'prepare image
    Dim imgFullSize As System.Drawing.Image

    'attempt to get the image       
    Dim sInputURL As String = HttpUtility.UrlDecode(Request.QueryString("IptFl"))
    If InStr(sInputURL, "http://") > 0 Or InStr(sInputURL, "https://") Then

        'from web url
        Dim imgWebRequest As System.Net.WebRequest
        Dim imgWebResponse As System.Net.WebResponse
        imgWebRequest = System.Net.WebRequest.Create(sInputURL)
        imgWebResponse = imgWebRequest.GetResponse()
        imgFullSize = System.Drawing.Image.FromStream(imgWebResponse.GetResponseStream())

    Else

        'from file
        imgFullSize = System.Drawing.Image.FromFile(Server.MapPath(sInputURL))

    End If



'   Dim props As PropertyItem() = imgFullSize.PropertyItems
'   For Each prop As PropertyItem In props
'       Response.Write(prop.Id.ToString() & "<br />")
'   Next




    'determine type
    Dim sFileExtension As String = "png"
    If Left(Right(sInputURL, 4), 1) = "." Then sFileExtension = Right(sInputURL, 3) 'for jpg, gif, etc
    If Left(Right(sInputURL, 5), 1) = "." Then sFileExtension = Right(sInputURL, 4) 'for tiff, jpeg, etc


    Dim jpgEncoder As ImageCodecInfo = GetEncoder(ImageFormat.Jpeg)
    Dim gifEncoder As ImageCodecInfo = GetEncoder(ImageFormat.Gif)
    Dim pngEncoder As ImageCodecInfo = GetEncoder(ImageFormat.Png)


    'set the quality
    Dim myEncoder As System.Drawing.Imaging.Encoder = System.Drawing.Imaging.Encoder.Quality
    Dim myEncoderParams As New EncoderParameters(1)
    Dim myEncoderQuality As New EncoderParameter(myEncoder, CType(100L, Int32))
    myEncoderParams.Param(0) = myEncoderQuality


    'save img to memory stream
    Dim ms As New MemoryStream()
    Select Case sFileExtension
        Case "jpg" : imgFullSize.Save(ms, jpgEncoder, myEncoderParams)
        Case "png", "gif" : imgFullSize.Save(ms, pngEncoder, myEncoderParams)
        Case Else : imgFullSize.Save(ms, pngEncoder, myEncoderParams)
    End Select


    'output the memory stream
    Response.ContentType = "image/" & sFileExtension
    ms.WriteTo(Response.OutputStream)

    '---> when I save the above image and look at the exif, it doesn't exist

End Sub


Private Function GetEncoder(ByVal format As ImageFormat) As ImageCodecInfo
    Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageDecoders()
    Dim codec As ImageCodecInfo
    For Each codec In codecs
        If codec.FormatID = format.Guid Then Return codec
    Next codec
    Return Nothing
End Function

1 个答案:

答案 0 :(得分:0)

所以这就行了。基本上我必须遍历源图像属性,并为每个属性在新图像中设置属性。

        'retrieve relative path to image
        Dim sSrc As String = HttpUtility.UrlDecode(Request.QueryString("IptFl"))


        'prepare image
        Dim oImg As System.Drawing.Image


        'attempt to get the image, either from web or local file
        If InStr(sSrc, "http://") > 0 Or InStr(sSrc, "https://") Then
            Dim oRequest As System.Net.WebRequest = System.Net.WebRequest.Create(sSrc)
            Dim oResponse As System.Net.WebResponse = oRequest.GetResponse()        
            oImg = System.Drawing.Image.FromStream(oResponse.GetResponseStream())
            oResponse.Close()
        Else
            oImg = System.Drawing.Image.FromFile(Server.MapPath(sSrc))
        End If

        'discard if image file not found
        If oImg Is Nothing Then Response.End()

        Dim sFileExt As String = Split(sSrc, ".")(UBound(Split(sSrc, ".")))


        Dim oCanvas As System.Drawing.Bitmap = New System.Drawing.Bitmap(oImg.Width, oImg.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555)

        For Each pi As PropertyItem In oImg.PropertyItems
            oCanvas.SetPropertyItem(pi)
        Next

        Dim oGraphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(oCanvas)
        oGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default
        oGraphic.DrawImage(oImg, 0, 0, oImg.Width, oImg.Height)
        Dim oStream As System.IO.MemoryStream = New System.IO.MemoryStream()
        oCanvas.Save(oStream, System.Drawing.Imaging.ImageFormat.Jpeg)

        Response.ContentType = "image/" & sFileExt

        'output the memory stream
        oStream.WriteTo(Response.OutputStream)
        Response.End()