从URL检索图像尺寸

时间:2014-01-18 09:58:24

标签: vb.net image url

我正在尝试从图片网址中检索图片尺寸。 这怎么可能? 我做了大量研究,但没有找到任何可以实现此目的的代码,所有信息都从本地磁盘上的图像获取图像尺寸,这不是我想要的。

有可能实现这个目标吗?

2 个答案:

答案 0 :(得分:5)

您不需要下载整个文件,只需要前几个字节。如果image为PNG,则宽度为17,18,19和20字节,高度为21,22,23和24字节。如果是GIF,则宽度为第7和第8个字节,高度为第9个和第10个字节。这对于JPG来说很复杂。请注意,PNG中的字节顺序是big-endian(255 - 000000FF),而GIF中的字节顺序是little-endian(255 - FF00)。这是代码:

Imports System
Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Threading
Imports Microsoft.VisualBasic

Public Class Form1

    Private Sub GetImageDimensions() Handles Button1.Click
        HTTPWebRequest_GetResponse.Main("http://www.example.com/image.png") 'without slash at end
        Do
            If HTTPWebRequest_GetResponse.done = True Then
                Dim width As Integer = HTTPWebRequest_GetResponse.width
                Dim height As Integer = HTTPWebRequest_GetResponse.height
                Exit Do
            End If
            If HTTPWebRequest_GetResponse.exception Then
                Exit Do 'prevents inifinite loop if exception occured
            End If
        Loop

    End Sub


End Class

Public Class RequestState
    ' This class stores the State of the request. 
    Public requestData As StringBuilder
    Public BufferRead() As Byte
    Public request As HttpWebRequest
    Public response As HttpWebResponse
    Public streamResponse As Stream

    Public Sub New()
        requestData = New StringBuilder("")
        request = Nothing
        streamResponse = Nothing
    End Sub 'New 
End Class 'RequestState


Class HTTPWebRequest_GetResponse

    Private BUFFER_SIZE As Integer = 1024
    Public Shared response As String
    Public Shared done As Boolean = False
    Public Shared length As Long = 1
    Public Shared progress As Integer
    Public Shared myHttpWebRequest As HttpWebRequest
    Public Shared myRequestState As New RequestState
    Public Shared status As String
    Private Shared body As Boolean = False
    Public Shared responseStream As Stream
    Private Shared offset As Integer
    Private Shared bytestoread As Integer
    Public Shared width As Integer
    Public Shared height As Integer
    Private Shared imageType As String
    Public Shared exception As Boolean = False

    Shared Sub Main(url As String)
        done = False
        exception = False
        Try
            If url.Substring(url.Length - 4) = ".png" Then
                myRequestState.BufferRead = New Byte(23) {}
                offset = 16
                bytestoread = 24
                imageType = "png"
            ElseIf url.Substring(url.Length - 4) = ".gif" Then
                myRequestState.BufferRead = New Byte(9) {}
                offset = 6
                bytestoread = 10
                imageType = "gif"
            Else
                Throw New NotSupportedException("You can only use this with PNG or GIF images.")
            End If


            ' Create a HttpWebrequest object to the desired URL.  
            myHttpWebRequest = WebRequest.Create(url)

            ' Create an instance of the RequestState and assign the previous myHttpWebRequest 
            ' object to its request field.   

            myRequestState.request = myHttpWebRequest

            ' Start the asynchronous request. 
            Dim result As IAsyncResult = CType(myHttpWebRequest.BeginGetResponse(New AsyncCallback(AddressOf RespCallback), myRequestState), IAsyncResult)
        Catch e As WebException
            exception = True
            Debug.WriteLine(ControlChars.Lf + "Main Exception raised!")
            Debug.WriteLine(ControlChars.Lf + "Message: " + e.Message)
            Debug.WriteLine(ControlChars.Lf + "Status: " + e.Status)
        Catch e As Exception
            exception = True
            Debug.WriteLine(ControlChars.Lf + "Main Exception raised!")
            Debug.WriteLine("Source : " + e.Source)
            Debug.WriteLine("Message : " + e.Message)
        End Try
    End Sub 'Main

    Private Shared Sub RespCallback(asynchronousResult As IAsyncResult)
        Try
            Dim myHttpWebRequest As HttpWebRequest = myRequestState.request
            myRequestState.response = CType(myHttpWebRequest.EndGetResponse(asynchronousResult), HttpWebResponse)

            ' Read the response into a Stream object. 
            Dim responseStream As Stream = myRequestState.response.GetResponseStream()
            myRequestState.streamResponse = responseStream

            ' Begin the Reading of the contents of the HTML page. 

            responseStream.Read(myRequestState.BufferRead, 0, bytestoread)
            If BitConverter.IsLittleEndian Then
                If imageType = "png" Then
                    height = BitConverter.ToInt32(myRequestState.BufferRead.Skip(offset).Reverse.Take(4).ToArray, 0)
                    width = BitConverter.ToInt32(myRequestState.BufferRead.Skip(offset).Reverse.Skip(4).Take(4).ToArray, 0)
                Else
                    width = BitConverter.ToInt16(myRequestState.BufferRead.Skip(offset).Skip(6).Take(2).ToArray, 0)
                    height = BitConverter.ToInt16(myRequestState.BufferRead.Skip(offset).Skip(8).Take(2).ToArray, 0)
                End If
            Else
                If imageType = "png" Then
                    width = BitConverter.ToInt32(myRequestState.BufferRead.Skip(offset).Skip(16).Take(4).ToArray, 0)
                    height = BitConverter.ToInt32(myRequestState.BufferRead.Skip(offset).Skip(20).Take(4).ToArray, 0)
                Else
                    height = BitConverter.ToInt16(myRequestState.BufferRead.Skip(offset).Reverse.Take(2).ToArray, 0)
                    width = BitConverter.ToInt16(myRequestState.BufferRead.Skip(offset).Reverse.Skip(2).Take(2).ToArray, 0)
                End If
            End If
            done = True
            Return
        Catch e As WebException
            exception = True
            Debug.WriteLine(ControlChars.Lf + "RespCallback Exception raised!")
            Debug.WriteLine(ControlChars.Lf + "Message: " + e.Message)
            Debug.WriteLine(ControlChars.Lf + "Status: " + e.Status)
        Catch ex As Exception
            exception = True
            Debug.WriteLine(ControlChars.Lf + "RespCallback Exception raised!")
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub 'RespCallback
End Class

代码很大,但我认为这只是为了下载足够的字节。

来源:https://en.wikipedia.org/wiki/Gif#Example_GIF_file https://en.wikipedia.org/wiki/Portable_Network_Graphics#Technical_details http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IHDR

答案 1 :(得分:0)

我不认为这是可能的。事情是......在从某个URL或文件或图片中检索任何信息之前,必须先下载它。这就是为什么Windows有临时文件夹的原因。一切都存储在临时文件夹中,包括您刚刚浏览互联网的场景。所以我的建议是做同样的事情,首先下载图片并将其保存在某处并检索你想要的信息,然后你可以删除该文件,如果你不再需要它了。