ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 在Excel单元格里绘图-WIA库的绘图功能

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-8-11 02:31 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

Excel的单元格也能绘图?没错!
利用WIA库提供的Vector向量数组,获取图片所有像素的ARGB数据,取出其中的RGB信息,就可以在Excel单元格里兴风作浪了。

  1. Sub ExcelDrawpic()
  2.     Cells.Interior.Color = xlNone
  3.     Dim myImg As Object    '定义MIA.Image对象
  4.     Set myImg = CreateObject("WIA.ImageFile")  '对象实例化

  5.     ' 打开图片文件,可更换成自己的图片,建议分辨率不要超过300*300,否则处理速度无法忍受
  6.     myImg.LoadFile "h:\girl2.jpg"

  7.     Dim width As Long
  8.     Dim height As Long
  9.     width = myImg.width       '图片宽度
  10.     height = myImg.height     '图片高度

  11.     Dim myVct As Object                     '定义MIA.Vector向量对象
  12.     Set myVct = CreateObject("WIA.Vector")  '创建Vector对象实例
  13.     Set myVct = myImg.ARGBData              '获取图片全部像素数据,存入向量

  14.     Dim colorARGB As String
  15.     Dim redVal As Byte, greenVal As Byte, blueVal As Byte

  16.     ' 关闭屏幕更新,为了提高绘图速度
  17.     Application.ScreenUpdating = False

  18.     Dim Row As Long, col As Long

  19.     For Row = 1 To height
  20.         For col = 1 To width
  21.             '从Vector向量里获取每个像素的ARGB值,A是指Alpha透明度,绘图时可不用,RGB数据才有用。
  22.             colorARGB = Hex(myVct((Row - 1) * width + col))
  23.             redVal = CInt("&H" & Mid(colorARGB, 3, 2))         '获取红色值
  24.             greenVal = CInt("&H" & Mid(colorARGB, 5, 2))       '绿色
  25.             blueVal = CInt("&H" & Mid(colorARGB, 7, 2))        '蓝色
  26.             
  27.             ' 确保行和列在 Excel 工作表的范围内绘图
  28.             If Row <= Rows.Count And col <= Columns.Count Then
  29.                 Cells(Row, col).Interior.Color = RGB(redVal, greenVal, blueVal) '根据像素颜色设置对应的单元格颜色
  30.             End If
  31.         Next col
  32.     Next Row

  33.     ' 恢复屏幕更新
  34.     Application.ScreenUpdating = True

  35.     ' 清理对象
  36.     Set myImg = Nothing
  37.     Set myVct = Nothing
  38. End Sub
复制代码


Excel绘图.png

读取图片在Excel里作像素画-WIA库的绘图功能.rar

316.54 KB, 下载次数: 60

评分

4

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-11 07:31 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
WIA库需要引用后才能保证程序正常运行。引用WIA库可在VBE窗口菜单里点击“工具”-“引用”,找到 "Microsoft Windows Image Acquisition Library V2.0" 勾选即可。
VBA引用WIA图像处理库1.png
VBA引用WIA图像处理库2.png

TA的精华主题

TA的得分主题

发表于 2024-8-11 11:22 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-12 00:17 | 显示全部楼层
再来个蒙版绘图
  1. Sub test()
  2. Cells.Interior.Color = xlNone  '清除画布
  3. Application.ScreenUpdating = False   '关闭屏幕显示

  4. Dim arrRGB(), brrRGB()         '定义图片与蒙版的RGB数组
  5. Dim fpath1 As String, fpath2 As String

  6. fpath1 = ThisWorkbook.Path & "\girl2.jpg"        '图片文件路径
  7. fpath2 = ThisWorkbook.Path & "\huazi.png"         '蒙版文件路径
  8.                                '蒙版以白色作背景,非白色区为图片展示区,
  9.                                '蒙版宽和高均不大于所展示图片的宽和高
  10.                               
  11. arrRGB = getArrRGB(fpath1)     '获取图片RGB数据
  12. brrRGB = getArrRGB(fpath2)     '获取蒙版的RGB数据

  13. Dim width As Integer, height As Integer
  14. width = UBound(brrRGB, 2)      '获取蒙版的宽
  15. height = UBound(brrRGB, 1)     '获取蒙版的高


  16. For i = 1 To UBound(brrRGB, 1)
  17.     For j = 1 To UBound(brrRGB, 2)
  18.         
  19.         maskR = brrRGB(i, j)(0)      '获取蒙版像素R值
  20.         maskG = brrRGB(i, j)(1)      '获取蒙版像素G值
  21.         maskB = brrRGB(i, j)(2)      '获取蒙版像素B值
  22.         picR = arrRGB(i, j)(0)       '获取图片像素R值
  23.         picG = arrRGB(i, j)(1)       '获取图片像素G值
  24.         picB = arrRGB(i, j)(2)       '获取图片像素B值
  25.         
  26.         '在蒙版蓝色区域(B值>=250)填充对应的图片颜色
  27.         '其它区域填充蒙版颜色
  28.         '当然也可以更改为别的什么规则
  29.         If maskR < 255 And maskG < 255 And maskB >= 250 Then
  30.             Cells(i, j).Interior.Color = RGB(picR, picG, picB)
  31.         Else
  32.             Cells(i, j).Interior.Color = RGB(maskR, maskG, maskB)
  33.         End If
  34.     Next
  35. Next

  36. Application.ScreenUpdating = True

  37. End Sub


  38. Function getArrRGB(fpath As String) As Variant
  39.     '此函数输入参数为完整的文件路径,将返回一个二维数组,
  40.     '数组的行数为图片的高(单位:像素)
  41.     '数组的列数为图片的宽(单位:像素)
  42.     '数组的每一项代表一个像素点的RGB数据,
  43.     '是一个嵌套的小数组,包含3个元素,即R、G、B值。
  44.     Dim myImg As Object
  45.     Set myImg = CreateObject("WIA.ImageFile")
  46.    
  47.     myImg.LoadFile fpath    '载入图片文件
  48.    
  49.     Dim width As Long
  50.     Dim height As Long
  51.     width = myImg.width
  52.     height = myImg.height

  53.     Dim myVct As Object
  54.     Set myVct = CreateObject("WIA.Vector")
  55.     Set myVct = myImg.ARGBData  '载入图片像素ARGB数据

  56.     Dim colorARGB As String
  57.     Dim redVal As Long, greenVal As Long, blueVal As Long

  58.     Dim Row As Long, col As Long
  59.     Dim arrRGB()
  60.     ReDim arrRGB(1 To height, 1 To width)
  61.    
  62.     For Row = 1 To height
  63.         For col = 1 To width
  64.             colorARGB = Hex(myVct((Row - 1) * width + col))
  65.             redVal = CInt("&H" & Mid(colorARGB, 3, 2))
  66.             greenVal = CInt("&H" & Mid(colorARGB, 5, 2))
  67.             blueVal = CInt("&H" & Mid(colorARGB, 7, 2))
  68.             ' 确保行和列在 Excel 工作表的范围内
  69.             If Row <= Rows.Count And col <= Columns.Count Then
  70.                 arrRGB(Row, col) = Array(redVal, greenVal, blueVal)
  71.             End If
  72.         Next col
  73.     Next Row
  74.     Set myImg = Nothing
  75.     Set myVct = Nothing
  76.     getArrRGB = arrRGB() '返回RGB数据的数组
  77. End Function

复制代码
使用蒙版显示图片.png

用蒙版显示图片-WIA库绘图探索.zip

97.59 KB, 下载次数: 27

TA的精华主题

TA的得分主题

发表于 2024-8-12 12:48 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
我也来助个兴
  1. Private Declare PtrSafe Function GetObject Lib "gdi32" Alias "GetObjectW" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
  2. Private Declare PtrSafe Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long

  3. Private Type BITMAPINFOHEADER
  4.     biSize          As Long
  5.     biWidth         As Long
  6.     biHeight        As Long
  7.     biBitCount      As Integer
  8.     biCompression   As Long
  9.     biSizeImage     As Long
  10.     biXPelsPerMeter As Long
  11.     biYPelsPerMeter As Long
  12. End Type

  13. Dim PicInfo As BITMAPINFOHEADER

  14. Function getBytes(Pic As IPictureDisp) As Byte()
  15.     GetObject Pic, LenB(PicInfo), PicInfo
  16.     ReDim picbits(PicInfo.biWidth * PicInfo.biHeight * 4 - 1) As Byte
  17.     GetBitmapBits Pic, UBound(picbits), picbits(0)
  18.     getBytes = picbits
  19. End Function

  20. Sub Pixel2Cell()
  21. Dim IPic As IPictureDisp, arrPic() As Byte, i&, j&, r&, Clr&
  22. Set IPic = LoadPicture("C:\Intel\LOGO.bmp")
  23. arrPic = getBytes(IPic)
  24. Application.ScreenUpdating = False
  25. Cells.Interior.Color = xlNone
  26. For i = 1 To PicInfo.biHeight
  27.   For j = 1 To PicInfo.biWidth
  28.     Clr = RGB(arrPic(r + 2), arrPic(r + 1), arrPic(r))
  29.     Cells(i, j).Interior.Color = Clr
  30.     r = r + 3
  31.   Next j
  32. Next i
  33. Application.ScreenUpdating = True
  34. Set IPic = Nothing
  35. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-12 16:08 | 显示全部楼层

这个牛,用gdi32库弄出来的好东西,正准备找点gdi这方面的资料看看呢。作者写点注释也好呀。感谢!

TA的精华主题

TA的得分主题

发表于 2024-8-12 16:24 | 显示全部楼层
jaxxcyh 发表于 2024-8-12 16:08
这个牛,用gdi32库弄出来的好东西,正准备找点gdi这方面的资料看看呢。作者写点注释也好呀。感谢!

抱歉啊,个人没有写注释的习惯,除非很复杂,有时间我会补一下注释重新发一下的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-12 16:40 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
图片反相显示,也就是胶卷底片的效果。逻辑很简单,就是每个像素RGB值取反。
  1. Sub test()
  2.     Cells.Interior.Color = xlNone        '清除画布
  3.     Application.ScreenUpdating = False   '关闭屏幕显示
  4.    
  5.     Dim fpath As String
  6.     fpath = ThisWorkbook.Path & "\girl2.jpg"     '图片文件路径
  7.     Dim arrRGB()                                 '定义图片RGB数组
  8.     arrRGB = getArrRGB(fpath)                    '获取图片RGB数据
  9.    
  10.     Dim width As Integer, height As Integer
  11.     width = UBound(arrRGB, 2)                    '获取图片的宽
  12.     height = UBound(arrRGB, 1)                   '获取图片的高
  13.    
  14.     Dim picR As Byte, picG As Byte, picB As Byte '定义RGB颜色变量
  15.    
  16.     For i = 1 To UBound(arrRGB, 1)
  17.         For j = 1 To UBound(arrRGB, 2)
  18.             picR = arrRGB(i, j)(0)       '获取图片像素R值
  19.             picG = arrRGB(i, j)(1)       '获取图片像素G值
  20.             picB = arrRGB(i, j)(2)       '获取图片像素B值
  21.             
  22.             '反显(底片)效果,逻辑是每个像素点RGB值分别取反
  23.             Cells(i, j).Interior.Color = RGB(Not picR, Not picG, Not picB)
  24.         Next
  25.     Next
  26.    
  27.     Application.ScreenUpdating = True
  28. End Sub

  29. Rem  -----------图片转RGB值的函数---------------
  30. Function getArrRGB(fpath As String) As Variant
  31.     '此函数输入参数为完整的文件路径,将返回一个二维数组,
  32.     '数组的行数为图片的高(单位:像素)
  33.     '数组的列数为图片的宽(单位:像素)
  34.     '数组的每一项代表一个像素点的RGB数据,
  35.     '是一个嵌套的小数组,包含3个元素,即R、G、B值。
  36.     Dim myImg As Object
  37.     Set myImg = CreateObject("WIA.ImageFile")
  38.    
  39.     myImg.LoadFile fpath    '载入图片文件
  40.    
  41.     Dim width As Long
  42.     Dim height As Long
  43.     width = myImg.width
  44.     height = myImg.height

  45.     Dim myVct As Object
  46.     Set myVct = CreateObject("WIA.Vector")
  47.     Set myVct = myImg.ARGBData  '载入图片像素ARGB数据

  48.     Dim colorARGB As String
  49.     Dim redVal As Byte, greenVal As Byte, blueVal As Byte

  50.     Dim Row As Long, col As Long
  51.     Dim arrRGB()
  52.     ReDim arrRGB(1 To height, 1 To width)
  53.    
  54.     For Row = 1 To height
  55.         For col = 1 To width
  56.             colorARGB = Hex(myVct((Row - 1) * width + col))
  57.             redVal = CInt("&H" & Mid(colorARGB, 3, 2))
  58.             greenVal = CInt("&H" & Mid(colorARGB, 5, 2))
  59.             blueVal = CInt("&H" & Mid(colorARGB, 7, 2))
  60.             ' 确保行和列在 Excel 工作表的范围内
  61.             If Row <= Rows.Count And col <= Columns.Count Then
  62.                 arrRGB(Row, col) = Array(redVal, greenVal, blueVal)
  63.             End If
  64.         Next col
  65.     Next Row
  66.     Set myImg = Nothing
  67.     Set myVct = Nothing
  68.     getArrRGB = arrRGB() '返回RGB数据的数组
  69. End Function

复制代码
反显效果-WIA绘图探索.png

反显图片-WIA库绘图探索.zip

131.29 KB, 下载次数: 14

TA的精华主题

TA的得分主题

发表于 2024-8-12 17:11 | 显示全部楼层
jaxxcyh 发表于 2024-8-12 16:08
这个牛,用gdi32库弄出来的好东西,正准备找点gdi这方面的资料看看呢。作者写点注释也好呀。感谢!

我另外一个帖子里面有一个比较完整的示例,工作表里有较详细的说明,但代码注释还是很少,供参考。

Intel.zip

181.13 KB, 下载次数: 24

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-8-12 17:58 | 显示全部楼层
大灰狼1976 发表于 2024-8-12 17:11
我另外一个帖子里面有一个比较完整的示例,工作表里有较详细的说明,但代码注释还是很少,供参考。

谢谢.................
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-21 22:05 , Processed in 0.044834 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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