He estado tratando de días para encontrar una manera de conseguir el ancho de la imagen de .los archivos png que residen en nuestro servidor. Estoy tratando de leer las primeras 24 bytes del archivo y analizar el ancho de bytes 17-20. He encontrado varias rutinas en la web, pero no han tenido éxito. Curiosamente, parece que me estoy poniendo a la altura de la bytes 21-24 decodificado de hexadecimal a decimal bien. He verificado el contenido del archivo mediante un hex viewer y el archivo está en buen estado. Aquí es la parte principal de la rutina:

Function ReadPNG(fichero)
Dim fso, ts, s, HW, nbytes
    HW = Array("0", "0")
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.OpenTextFile(Server.MapPath("\forums\attachments/" & fichero), 1)
    s = Right(ts.Read(24), 8)
    HW(0) = HexToDec(HexAt(s,3) & HexAt(s,4))
    HW(1) = HexToDec(HexAt(s,7) & HexAt(s,8))
    ts.Close
    ReadPNG = HW
End Function

Function HexAt(s, n)
    HexAt = Hex(AscAt(s, n))
End Function

Function HexToDec(ByVal HexVal)

Dim i, num, part
num = 0
For I = 1 to Len(HexVal)
    part = Mid(StrReverse(UCase(HexVal)), I, 1)
    If IsNumeric(part) Then
        num = num + (CInt(part) * 16 ^ (I - 1) )
    Else
        num = num + ( (Asc(part) - 55) * 16^(I - 1) )
    End If
Next

HexToDec = num

End Function

Como un ejemplo, mi archivo hex «00 00 01 80» en el ancho de bytes (decimal 384)
y hex «00 00 01 32» en la altura bytes (decimal 306)

Estoy recibiendo una altura máxima de 306, sino a ti ancho está volviendo «0011» (decimal 17).

Estoy totalmente stummped! No tengo para utilizar esta rutina.

Gracias,
Jim

  • En su título, ¿quieres decir que en el lado del servidor VBScript?
  • Claramente no dejan de lado del servidor, he corregido el título para usted.
InformationsquelleAutor Jim | 2010-03-07

3 Comentarios

  1. 4

    Aquí es de un post que vi hace un rato, parece que podría simplificar un poco las cosas. Yo no lo he probado, así que déjame saber tus resultados.

    <%
    dim iWidth, iheight
    sub ImgDimension(img)
    dim myImg, fs
    Set fs= CreateObject("Scripting.FileSystemObject")
    if not fs.fileExists(img) then exit sub
    set myImg = loadpicture(img)
    iWidth = round(myImg.width / 26.4583)
    iheight = round(myImg.height / 26.4583)
    set myImg = nothing
    end sub
    
    ImgDimension(Server.MapPath("server image file"))
    %> 

    Ver aquí para el post: http://www.haneng.com/asp-forum/ASP—Get-Image-Size_12971.html

    ACTUALIZACIÓN: Viendo que este método no funciona en 64 bits. Aquí hay un enlace a otro método alternativo: http://www.4guysfromrolla.com/webtech/050300-1.shtml

    • LoadPicture docs: msdn.microsoft.com/en-us/library/66bd1sx9(VS.85).aspx no hace mención expresa PNG, pero bien puede servirles de apoyo.
    • Buen punto, +1 gracias @T. J. Crowder
    • Si no funciona con png, puedo utilizar otro tipo de archivo. Voy a probar esta y aconsejar. Gracias chicos!
    • He visto algunos posts que muestran esto con PNG, así que soy optimista.
    • Oh boy! Loadpicture no funciona en plataformas de 64 bits! De suerte allí.
    • He actualizado mi respuesta con la otra alternativa.
    • Durilai, Sí, en realidad he tratado de lógica. Se apunta a la posición incorrecta en el archivo que he corregido, pero que la rutina parece que vuelve el problema que he descrito.
    • La idea aquí es limitar el ancho de muestra en el navegador. Más de 820 píxeles deben mostrar en 820. Por desgracia, el CSS Max-width no funciona en IE funciona bien en Firefox.
    • Ahhh, veo el problema… que necesito para convertir la primera parte de el archivo en una cadena ascii del archivo binario. No hay código de 4Guys para ello. Voy a probar eso.
    • A continuación, ejecute la vbscript utilizando la versión de 32 bits de wscript (en esa máquina de 64 bits). Ejemplo: c:\windows\syswow64\wscript c:\path\to\your.vbs

  2. 2

    Puedo usar esta sencilla función para devolver la anchura, la altura y el tamaño del archivo (por ejemplo. 640 x 480 – 200KBytes):

       Function ImgDim(img)
        Dim objFSO, objGF, objLP, imgWdt, imgHgt, imgSiz
        img = Server.MapPath("/pictures/"& img) 'path to picture
        Set objFSO= CreateObject("Scripting.FileSystemObject")
        If objFSO.fileExists(img) Then
         Set objGF = objFSO.GetFile(img)
          imgSiz = objGF.Size
         Set objGF = Nothing
         Set objLP = loadpicture(img)
          imgWdt = round(objLP.width / 26.4583)
          imgHgt = round(objLP.height / 26.4583)
         Set objLP = Nothing
         Set fs = Nothing
         ImgDim = imgWdt &"x"& imgHgt &" - "& imgSiz/1024 &"KBytes"
        End If
       End Function

    funciona de maravilla, espero que ayude.

  3. 0

    Aquí es un conjunto genérico de funciones encontré hace años para la obtención de información en una imagen. Voy a poner la forma en que lo he estado usando en la final.

    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    ':::                                                             :::'
    ':::  This routine will attempt to identify any filespec passed  :::'
    ':::  as a graphic file (regardless of the extension). This will :::'
    ':::  work with BMP, GIF, JPG and PNG files.                     :::'
    ':::                                                             :::'
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    ':::          Based on ideas presented by David Crowell          :::'
    ':::                   (credit where due)                        :::'
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    '::: blah blah blah blah blah blah blah blah blah blah blah blah :::'
    '::: blah blah blah blah blah blah blah blah blah blah blah blah :::'
    '::: blah blah     Copyright *c* MM,  Mike Shaffer     blah blah :::'
    '::: blah blah      ALL RIGHTS RESERVED WORLDWIDE      blah blah :::'
    '::: blah blah  Permission is granted to use this code blah blah :::'
    '::: blah blah   in your projects, as long as this     blah blah :::'
    '::: blah blah      copyright notice is included       blah blah :::'
    '::: blah blah blah blah blah blah blah blah blah blah blah blah :::'
    '::: blah blah blah blah blah blah blah blah blah blah blah blah :::'
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    ':::                                                             :::'
    ':::  This function gets a specified number of bytes from any    :::'
    ':::  file, starting at the offset (base 1)                      :::'
    ':::                                                             :::'
    ':::  Passed:                                                    :::'
    ':::       flnm        => Filespec of file to read               :::'
    ':::       offset      => Offset at which to start reading       :::'
    ':::       bytes       => How many bytes to read                 :::'
    ':::                                                             :::'
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    function GetBytes(flnm, offset, bytes)
    Dim objFSO
    Dim objFTemp
    Dim objTextStream
    Dim lngSize
    on error resume next
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    ' First, we get the filesize'
    Set objFTemp = objFSO.GetFile(flnm)
    lngSize = objFTemp.Size
    set objFTemp = nothing
    fsoForReading = 1
    Set objTextStream = objFSO.OpenTextFile(flnm, fsoForReading)
    if offset > 0 then
    strBuff = objTextStream.Read(offset - 1)
    end if
    if bytes = -1 then        ' Get All!'
    GetBytes = objTextStream.Read(lngSize)  'ReadAll'
    else
    GetBytes = objTextStream.Read(bytes)
    end if
    objTextStream.Close
    set objTextStream = nothing
    set objFSO = nothing
    end function
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    ':::                                                             :::'
    ':::  Functions to convert two bytes to a numeric value (long)   :::'
    ':::  (both little-endian and big-endian)                        :::'
    ':::                                                             :::'
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    function lngConvert(strTemp)
    lngConvert = clng(asc(left(strTemp, 1)) + ((asc(right(strTemp, 1)) * 256)))
    end function
    function lngConvert2(strTemp)
    lngConvert2 = clng(asc(right(strTemp, 1)) + ((asc(left(strTemp, 1)) * 256)))
    end function
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    ':::                                                             :::'
    ':::  This function does most of the real work. It will attempt  :::'
    ':::  to read any file, regardless of the extension, and will    :::'
    ':::  identify if it is a graphical image.                       :::'
    ':::                                                             :::'
    ':::  Passed:                                                    :::'
    ':::       flnm        => Filespec of file to read               :::'
    ':::       width       => width of image                         :::'
    ':::       height      => height of image                        :::'
    ':::       depth       => color depth (in number of colors)      :::'
    ':::       strImageType=> type of image (e.g. GIF, BMP, etc.)    :::'
    ':::                                                             :::'
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
    function gfxSpex(flnm, width, height, depth, strImageType)
    dim strPNG 
    dim strGIF
    dim strBMP
    dim strType
    strType = ""
    strImageType = "(unknown)"
    gfxSpex = False
    strPNG = chr(137) & chr(80) & chr(78)
    strGIF = "GIF"
    strBMP = chr(66) & chr(77)
    strType = GetBytes(flnm, 0, 3)
    if strType = strGIF then                ' is GIF'
    strImageType = "GIF"
    Width = lngConvert(GetBytes(flnm, 7, 2))
    Height = lngConvert(GetBytes(flnm, 9, 2))
    Depth = 2 ^ ((asc(GetBytes(flnm, 11, 1)) and 7) + 1)
    gfxSpex = True
    elseif left(strType, 2) = strBMP then        ' is BMP'
    strImageType = "BMP"
    Width = lngConvert(GetBytes(flnm, 19, 2))
    Height = lngConvert(GetBytes(flnm, 23, 2))
    Depth = 2 ^ (asc(GetBytes(flnm, 29, 1)))
    gfxSpex = True
    elseif strType = strPNG then            ' Is PNG'
    strImageType = "PNG"
    Width = lngConvert2(GetBytes(flnm, 19, 2))
    Height = lngConvert2(GetBytes(flnm, 23, 2))
    Depth = getBytes(flnm, 25, 2)
    select case asc(right(Depth,1))
    case 0
    Depth = 2 ^ (asc(left(Depth, 1)))
    gfxSpex = True
    case 2
    Depth = 2 ^ (asc(left(Depth, 1)) * 3)
    gfxSpex = True
    case 3
    Depth = 2 ^ (asc(left(Depth, 1)))  '8'
    gfxSpex = True
    case 4
    Depth = 2 ^ (asc(left(Depth, 1)) * 2)
    gfxSpex = True
    case 6
    Depth = 2 ^ (asc(left(Depth, 1)) * 4)
    gfxSpex = True
    case else
    Depth = -1
    end select
    else
    strBuff = GetBytes(flnm, 0, -1)        ' Get all bytes from file'
    lngSize = len(strBuff)
    flgFound = 0
    strTarget = chr(255) & chr(216) & chr(255)
    flgFound = instr(strBuff, strTarget)
    if flgFound = 0 then
    exit function
    end if
    strImageType = "JPG"
    lngPos = flgFound + 2
    ExitLoop = false
    do while ExitLoop = False and lngPos < lngSize
    do while asc(mid(strBuff, lngPos, 1)) = 255 and lngPos < lngSize
    lngPos = lngPos + 1
    loop
    if asc(mid(strBuff, lngPos, 1)) < 192 or asc(mid(strBuff, lngPos, 1)) > 195 then
    lngMarkerSize = lngConvert2(mid(strBuff, lngPos + 1, 2))
    lngPos = lngPos + lngMarkerSize  + 1
    else
    ExitLoop = True
    end if
    loop
    if ExitLoop = False then
    Width = -1
    Height = -1
    Depth = -1
    else
    Height = lngConvert2(mid(strBuff, lngPos + 4, 2))
    Width = lngConvert2(mid(strBuff, lngPos + 6, 2))
    Depth = 2 ^ (asc(mid(strBuff, lngPos + 8, 1)) * 8)
    gfxSpex = True
    end if
    end if
    end function

    He estado usando para generar un estudio aleatorizado de archivo XML para una biblioteca de imágenes. La secuencia de comandos sólo se ejecute cuando termino de cargar una nueva imagen a la biblioteca.

    Aquí está el uso de: (o al menos como lo he usado)

    'collect the image information into an array'
    Dim blnGfxSpex, width, height, colors, strType
    intCount = 0
    For Each objFile In objFS.GetFolder(".\images").Files
    If LCase(Right(objFile.Name, 4)) = ".jpg" and intCount <= intNumOfFiles Then
    blnGfxSpex = gfxSpex((".\images\" & objFile.Name), width, height, colors, strType)
    arrImages(intCount) = "<image>" & vbNewLine & _
    "<filename>" & objFile.Name & "</filename>" & vbNewLine & _
    "<caption></caption>" & vbNewLine & _
    "<width>" & width & "</width>" & vbNewLine & _
    "<height>" & height & "</height>" & vbNewLine & _
    "</image>" & vbNewLine
    intCount = intCount + 1
    End If
    Next

    Como se puede ver, estoy inicializando las variables para el ancho, la altura, etc. y la función de los conjuntos de ellos, según proceda. Sé que no es kosher para el uso de variables globales como que, pero funciona.

    Rendimiento no es tan malo como se podría pensar. En este caso particular, yo soy el filtrado de la imagen de la biblioteca sólo en Jpg, pero que es debido a una limitación en la imagen de la biblioteca de el XML es para, no debido a una limitación de las funciones.

    • Esto no funciona en ninguno de mis archivos PNG. Son válidos, photoshop y vista previa (macos) tanto reconocer, como lo hace el navegador. Me estoy poniendo el ancho como un gran número, pero la altura es la correcta, por ejemplo, 02386C87651E40209D6802DAD046F3FE.png => -15430, 300 La fuente artículo está aquí: 4guysfromrolla.com/webtech/050300-1.shtml.

Dejar respuesta

Please enter your comment!
Please enter your name here