【问题标题】:Retrieve image dimensions from URL从 URL 检索图像尺寸
【发布时间】:2014-01-18 09:58:24
【问题描述】:

我正在尝试从图像 URL 检索图像尺寸。 这怎么可能? 我做了很多研究,还没有找到任何代码可以实现这一点,所有信息都从本地磁盘上的图像中获取图像尺寸,这不是我想要的。

有可能实现吗?

【问题讨论】:

    标签: vb.net image url


    【解决方案1】:

    您不需要下载整个文件,只需下载前几个字节。如果图像是PNG,宽度在第17、18、19和20个字节,高度在第21、22、23和24个字节。如果是GIF,宽度在第 7 和第 8 字节,高度在第 9 和第 10 字节。 JPG 很复杂。请注意,PNG 中的字节顺序是大端(255 - 000000FF),而 GIF 中的字节顺序是小端(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

    【讨论】:

    • 嘿 - 这太棒了!似乎正是我正在寻找的东西,您是否可以提供代码/示例?如果您愿意,请更新您的答案,我相信它可以帮助其他人。
    • @user3102516 代码已添加!
    • 我的立场是正确的。感谢您提供此信息@srka。我知道就像 mp3 文件一样,信息位于整个事物的某些字节中,但我从不知道您可以部分地从整个事物中获取信息。谢谢。
    【解决方案2】:

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

    【讨论】:

    • 问题是我必须过滤数百张图像。所以下载 500 张图片需要很长时间,然后过滤它们,最终在 10 分钟下载 500 张之后,我可能会留下 20 张图片。所以非常耗时。
    • 我以前做过这样的事情。这是一项 SEO 工作,如果我要手动搜索关键字和图片等内容,则需要一个多月的时间才能完成。有一次我不得不处理 23,000 个链接。所以我决定创建一个机器人程序来完成这项工作。完成全部扫描大约需要 3 个小时。我不知道是否有更好的方法可以做到这一点,但根据我阅读过的无数教程,这是唯一的方法。如果有人有更好的想法,我会非常感激,如果它被分享,我可以学习:)
    • 还有一件事……除非您拥有超级计算机,否则您的程序无法在几秒钟内扫描数百张图片。毕竟,就我而言,3 小时比 1 个月要好得多。
    • 您以前听说过流吗?
    • @Neolisk,是的,先生,我听说过流。我实际上制作了一个可以在线流式传输实时视频的 Android 应用程序。不幸的是,我从来没有做过任何关于使用 VB.NET 流式传输图片和东西的事情。如果你对此有任何想法,你可以分享它,这样我们都可以向你学习。谢谢:)
    猜你喜欢
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多