ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 7549|回复: 14

[分享] GetImageSize获取图像尺寸(宽*高)

[复制链接]

TA的精华主题

TA的得分主题

发表于 2013-11-11 14:03 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:图像处理和GDI
前几天见论坛上有人需要,批量获取硬盘内图像文件的尺寸(宽*高),
闲得无聊,写了一个获取图像尺寸的函数,在网络上的vb版,算是支持
格式比较全的了,目前支持以下文件格式png,jpg,bmp,gif,psd,tif(tiff),jp2,
其中bmp支持windows版本和IBM版本,tif支持PC版本和Mac版本
支持的文件即使扩展名错误也可正确识别,可输出正确的扩展名。
  1. Type ImageSize
  2.     P_Type As String
  3.     Width As Long
  4.     Height As Long
  5. End Type
  6. Function BinVal(bin)    '低位在前Intel
  7.     Dim i
  8.     Dim ret: ret = 0
  9.     For i = LenB(bin) To 1 Step -1
  10.         ret = ret * 256 + AscB(MidB(bin, i, 1))
  11.     Next
  12.     BinVal = ret
  13. End Function

  14. Function BinVal2(bin)    '高位在前Motorola
  15.     Dim i
  16.     Dim ret: ret = 0
  17.     For i = 1 To LenB(bin)
  18.         ret = ret * 256 + AscB(MidB(bin, i, 1))
  19.     Next
  20.     BinVal2 = ret
  21. End Function

  22. Function GetImageSize(fdata) As ImageSize
  23.     Dim bFlag, fsize, ADOS, n&
  24.     fsize = CLng(LenB(fdata))    '取得数据尺寸
  25.     If fsize = 0 Then Exit Function
  26.     Set ADOS = CreateObject("ADODB.Stream")
  27.     With ADOS
  28.         .Type = 1
  29.         '    .Mode = 3
  30.         .Open
  31.         .LoadFromFile fdata
  32.         .Position = 0
  33.         '写文本对象读取图像长宽和类型
  34.         .Position = 0    '重置数据开始位置
  35.         bFlag = .Read(3)
  36.         If IsNull(bFlag) Then
  37.             GetImageSize.P_Type = "unknow"
  38.             GetImageSize.Width = 0
  39.             GetImageSize.Height = 0
  40.             Exit Function
  41.         End If
  42.         '取文件类型和长宽
  43.         Select Case Hex(BinVal(bFlag))
  44.         Case "4E5089"    'png********************
  45.             .Read (13)
  46.             GetImageSize.P_Type = "png"
  47.             GetImageSize.Width = BinVal2(.Read(4))
  48.             GetImageSize.Height = BinVal2(.Read(4))
  49.         Case "464947"    'gif*******************
  50.             .Read (3)
  51.             GetImageSize.P_Type = "gif"
  52.             GetImageSize.Width = BinVal(.Read(2))
  53.             GetImageSize.Height = BinVal(.Read(2))
  54.         Case "504238"    'psd*********************
  55.             .Read (13)
  56.             GetImageSize.P_Type = "psd"
  57.             GetImageSize.Height = BinVal2(.Read(2))
  58.             .Read (2)
  59.             GetImageSize.Width = BinVal2(.Read(2))
  60.         Case "FFD8FF"    'jpg**********************
  61.             Dim p1
  62.             Do
  63.                 Do: p1 = BinVal(.Read(1)): Loop While p1 = 255 And Not .EOS
  64.                 If p1 > 191 And p1 < 196 Then Exit Do Else .Read (BinVal2(.Read(2)) - 2)
  65.                 Do: p1 = BinVal(.Read(1)): Loop While p1 < 255 And Not .EOS
  66.             Loop While True
  67.             .Read (3)
  68.             GetImageSize.P_Type = "jpg"
  69.             GetImageSize.Height = BinVal2(.Read(2))
  70.             GetImageSize.Width = BinVal2(.Read(2))
  71.         Case "4D4D", "2A4949"  'tif***************
  72.             If Hex(BinVal(bFlag)) = "2A4949" Then
  73.                 .Position = 4
  74.                 .Position = BinVal(.Read(4)) + 2
  75.                 Do
  76.                     If BinVal(.Read(2)) = 256 Then Exit Do
  77.                     .Read (10)
  78.                 Loop
  79.                 n = (BinVal(.Read(2)) \ 2) * 2
  80.                 .Read (4)
  81.                 GetImageSize.P_Type = "tif"
  82.                 GetImageSize.Width = BinVal(.Read(n))
  83.                 .Read (12 - n)
  84.                 GetImageSize.Height = BinVal(.Read(n))
  85.             Else
  86.                 .Position = 4
  87.                 .Position = BinVal2(.Read(4)) + 2
  88.                 Do
  89.                     If BinVal2(.Read(2)) = 256 Then Exit Do
  90.                     .Read (10)
  91.                 Loop
  92.                 n = (BinVal2(.Read(2)) \ 2) * 2
  93.                 .Read (4)
  94.                 GetImageSize.P_Type = "tif"
  95.                 GetImageSize.Width = BinVal2(.Read(n))
  96.                 .Read (12 - n)
  97.                 GetImageSize.Height = BinVal2(.Read(n))
  98.             End If
  99.         Case "0" '************jp2********************
  100.             .Read (1)
  101.             If Hex(BinVal(.Read(4))) = "2020506A" Then
  102.                 .Read (4)
  103.                 Do    '定位图像框
  104.                     n = BinVal2(.Read(4))
  105.                     If Hex(BinVal(ADOS.Read(4))) = "6832706A" Then Exit Do
  106.                     If n = 1 Then
  107.                         n = BinVal2(.Read(8))
  108.                         .Read (n - 16)
  109.                     Else
  110.                         .Read (n - 8)
  111.                     End If
  112.                 Loop
  113.                 If n = 1 Then .Read (8)
  114.                 Do    '定位图像头框
  115.                     n = BinVal2(.Read(4))
  116.                     If Hex(BinVal(ADOS.Read(4))) = "72646869" Then Exit Do
  117.                     If n = 1 Then
  118.                         n = BinVal2(.Read(8))
  119.                         .Read (n - 16)
  120.                     Else
  121.                         .Read (n - 8)
  122.                     End If
  123.                 Loop
  124.                 GetImageSize.P_Type = "jp2"
  125.                 GetImageSize.Height = BinVal2(.Read(4))
  126.                 GetImageSize.Width = BinVal2(.Read(4))
  127.             End If
  128.         Case Else    'bmp****************************
  129.             If bFlag(0) = 66 And bFlag(1) = 77 Then
  130.                 .Read (11)
  131.                 If BinVal(.Read(4)) = 12 Then n = 2 Else n = 4    '区分Windows和O/S2
  132.                 GetImageSize.P_Type = "bmp"
  133.                 GetImageSize.Width = BinVal(.Read(n))
  134.                 GetImageSize.Height = BinVal(.Read(n))
  135.             Else
  136.                 GetImageSize.P_Type = ""
  137.             End If
  138.         End Select
  139.         .Close
  140.     End With
  141.     Set ADOS = Nothing
  142.     Select Case GetImageSize.P_Type
  143.     Case "png", "jpg", "bmp", "gif", "psd", "tif", "jp2"
  144.     Case Else
  145.         GetImageSize.Width = 0
  146.         GetImageSize.Height = 0
  147.         GetImageSize.P_Type = "unknow"
  148.     End Select
  149. End Function
复制代码
以下是测试代码
  1. Sub ttt()
  2.     Dim st, im As ImageSize
  3.     st = Application.GetOpenFilename("图片文件 (*.jp*;*.psd;*.tif*;*.png;*.gif;*.bmp), *.jp*;*.psd;*.tif*;*.png;*.gif;*.bmp")
  4.     im = GetImageSize(st)
  5.     MsgBox im.P_Type & "文件" & vbCrLf & "宽度:" & im.Width & vbCrLf & "高度:" & im.Height
  6. End Sub
复制代码

评分

3

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-11-11 14:26 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
希望有个附件参考一下

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-11 17:48 | 显示全部楼层
dyzx 发表于 2013-11-11 14:26
希望有个附件参考一下

给一个获取指定文件夹及其子文件夹中所有图片 路径*类型*宽*高 的例子
因为用Dos命令搜索文件,所以请不要关闭cmd窗口,完成后会自动关闭
时间都花在搜索文件上了,实际上GetImageSize函数用时很少!
宽高.7z (13.17 KB, 下载次数: 130)

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-12-30 17:21 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
高手高手高手高手高手高手高手高手高手高手

TA的精华主题

TA的得分主题

发表于 2016-6-26 23:03 | 显示全部楼层
太棒了!!非常感谢!!!

TA的精华主题

TA的得分主题

发表于 2016-6-28 21:35 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2017-9-14 22:38 | 显示全部楼层
  1. Function GetImageSize(ByVal FileName As String, _
  2.                    ImageSize As ImgDimType, _
  3.                    Ext As String) As Boolean
  4.     '参数1:FileName, 输入待检查的图片文件名,支持png/jpg/gif/bmp
  5.     '参数2:ImageSize, 返回图片的尺寸信息
  6.     '参数3:Ext,返回图片文件的真实扩展名
  7.     Dim handle As Integer, isValidImage As Boolean
  8.     Dim byteArr(255) As Byte, i As Integer
  9.     isValidImage = False
  10.     ImageSize.Height = 0
  11.     ImageSize.Width = 0
  12.     handle = FreeFile
  13.     On Error GoTo endFunction
  14.     Open FileName For Binary Access Read As #handle
  15.         Get handle, , byteArr     'open file and get 256 byte chunk
  16.     Close #handle
  17.     If byteArr(0) = &HFF And byteArr(1) = &HD8 Then   'check for jpg header (SOI): &HFF and &HD8, contained in first 2 bytes
  18.         isValidImage = True
  19.     Else
  20.         GoTo checkGIF
  21.     End If
  22.     For i = 0 To 255    'check for SOF marker: &HFF and &HC0 TO &HCF
  23.         If byteArr(i) = &HFF And byteArr(i + 1) >= &HC0 _
  24.             And byteArr(i + 1) <= &HCF Then
  25.             ImageSize.Height = byteArr(i + 5) * 256 + byteArr(i + 6)
  26.             ImageSize.Width = byteArr(i + 7) * 256 + byteArr(i + 8)
  27.             Exit For
  28.         End If
  29.     Next i
  30.     Ext = "jpg"
  31.     GoTo endFunction
  32. checkGIF:
  33.     If byteArr(0) = &H47 And byteArr(1) = &H49 And byteArr(2) = &H46 _
  34.         And byteArr(3) = &H38 Then 'check for GIF header
  35.         ImageSize.Width = byteArr(7) * 256 + byteArr(6)
  36.         ImageSize.Height = byteArr(9) * 256 + byteArr(8)
  37.         isValidImage = True
  38.     Else
  39.         GoTo checkBMP
  40.     End If
  41.     Ext = "gif"
  42.     GoTo endFunction
  43. checkBMP:
  44.     'check for BMP header
  45.     If byteArr(0) = 66 And byteArr(1) = 77 Then
  46.         isValidImage = True
  47.     Else
  48.         GoTo checkPNG
  49.     End If
  50.     'get record type info
  51.     If byteArr(14) = 40 Then
  52.         'get width and height of BMP
  53.         ImageSize.Width = byteArr(21) * 256 ^ 3 + byteArr(20) * 256 ^ 2 _
  54.             + byteArr(19) * 256 + byteArr(18)
  55.         ImageSize.Height = byteArr(25) * 256 ^ 3 + byteArr(24) * 256 ^ 2 _
  56.             + byteArr(23) * 256 + byteArr(22)
  57.         'another kind of BMP
  58.     ElseIf byteArr(17) = 12 Then
  59.         'get width and height of BMP
  60.         ImageSize.Width = byteArr(19) * 256 + byteArr(18)
  61.         ImageSize.Height = byteArr(21) * 256 + byteArr(20)
  62.     End If
  63.     'get image type and exit
  64.     Ext = "bmp"
  65.     GoTo endFunction
  66. checkPNG:
  67.     If byteArr(0) = &H89 And byteArr(1) = &H50 And byteArr(2) = &H4E _
  68.         And byteArr(3) = &H47 Then 'check for PNG header
  69.         ImageSize.Width = byteArr(18) * 256 + byteArr(19)
  70.         ImageSize.Height = byteArr(22) * 256 + byteArr(23)
  71.         isValidImage = True
  72.     Else
  73.         GoTo endFunction
  74.     End If
  75.     Ext = "png"
  76. endFunction:
  77.     GetImageSize = isValidImage
  78. End Function
复制代码

TA的精华主题

TA的得分主题

发表于 2019-3-4 23:26 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2019-5-24 10:50 | 显示全部楼层
刚测试了下, 可以获取到子文件夹, 蛮好的, 不过, 可否增加显示这些图片的文件大小呢, 楼主?

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-6-3 11:25 来自手机 | 显示全部楼层
excel_hero 发表于 2019-5-24 10:50
刚测试了下, 可以获取到子文件夹, 蛮好的, 不过, 可否增加显示这些图片的文件大小呢, 楼主?

自己用FileLen函数获取一下就可以了啊
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-20 11:46 , Processed in 0.051040 second(s), 14 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表