利用PIL的Image将图片像素写入xlwings 的 EXCEL单元格

直接上代码:

from PIL import Image
import xlwings as xw
b1 = xw.Book()
sht = b1.sheets[0]
bg = Image.open("11.png")
bg = bg.convert("RGBA")
h = bg.size[0]
w = bg.size[1]
print(h,w)
for x in range(h):
    for y in range(w):
            #sht[y,x].value = bg.getpixel((x,y))[0]
            if (bg.getpixel((x,y))[:3] != (255,255,255)):
                sht[y,x].value = "%s, %s" % (x + 1, y + 1)

 

----------------------------------------------分隔线----------------------------------------------------

上面的方法可取但是出图速度比较慢,来个快的:

def get_desktop():#桌面路径
    import winreg
    key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 
                         r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders')
    return winreg.QueryValueEx(key,"Desktop")[0]

def get_rgb(rgb):
    rgb = rgb[0] + (rgb[1] * 256) + (rgb[2] * 256 * 256)#RGB换算成VBA识别的color值
    return rgb

def getV2C(shName):
    from PIL import Image
    import xlwings as xw
    import numpy as np
    b1 = xw.Book()
    sht = b1.sheets[0]
    sht.name = shName[:-4]
    sht.range("A:XFD").api.ColumnWidth = 1.78    #设置所有的列宽为1.78(相当于26像素)与行高的初始值相同。
    sht.range("A1").api.Application.ReferenceStyle = 2    #设置单元格的引用样式为R1C1(因为VAB对象结构是无限循环的,所以调用起来非常方便)
#     sht.range("A1").api.Application.ActiveWindow.Zomm = 15    #这一方法放到VBA脚本里面去了,在此执行容易出错
    bg = Image.open(shName)
    bg = bg.convert("RGBA")
    w = bg.size[0]
    h = bg.size[1]
    # print(w,h)#打印宽和高
    ilist = np.zeros((h,w))    #新建一个多维数组,这也是调用np的唯一目的,方便快捷!
    #注意这里先高后宽是因为图片像素坐标系统与list是不一样的,此处相当于行列互换。否则结果可能不是你想要的。
    ilist = ilist.tolist()    #将np对象转换为pytohn的list
    # print(len(ilist))
    for y in range(h):
        for x in range(w):
            rgb = get_rgb(bg.getpixel((x,y)))
            transparency = bg.getpixel((x,y))[3]
    #         print(x,y,bg.getpixel((x,y)),rgb,transparency)
            if bg.getpixel((x,y))[:3] != (255,255,255) and transparency >= 254:
    #           白色的RGB值为(255,255,255),因为EXCEL默认单元格曾经背景就是白色,所以只要不是白色和纯透明的色就赋值rgb,否则赋空值
                ilist[y][x] = rgb
            else:
                ilist[y][x] = None
                
    sht.range("a1").value = ilist    #直接给A1单元格填入ilist的值
    sht.range("a1").api.SpecialCells(2, 23).NumberFormatLocal = ";;;"#为非空单元格设置单元格格式
    try:
        v2c = b1.app.macro("v2c.getcolor")#调用加载项中的SUB,模块名为  v2c ,sub名为  getcolor代码如下
        """
        新建一个excel文件,打开VBA工程,插入模块,修改模块名为: v2c
        输入以下代码,并另存为xla或xlam
        再将此文件添加到EXCEL加载项中
        Sub getcolor()
            Dim Rngs As Range
            Set Rngs = Range("a1").SpecialCells(2, 23)
            For Each Rng In Rngs:
            With Rng
                .Interior.Color = .Value
            End With
            Next
            ActiveWindow.Zoom = 15
        End Sub
        """
        v2c()#执行指向的vba过程,即getcolor()
    except:
        print("调用VBA模块失败")
    else:
        ipath = get_desktop()
        b1.save("%s\\%s.xlsx" % (ipath, shName[:-4]))    #保存到桌面
    bg    #显示目标图片,这是在一切操作完成之后执行,当完成用
        #getV2C END
iName = "bunny girl.png"
#执行命令前手动打开一个空的excel实例(即双击EXCEK图标,新建一个空文档),否则会无法调用加载项。
getV2C(iName)
Sub getcolorz()
    Dim Rngs As Range, mi As Range
    Set mi = Range("xfd1")

    Set Rngs = Range("a1").SpecialCells(2, 23)

        For i = 0 To Rngs.Count
            mi.Value = 9E+99
            For Each Rng In Rngs:
            
                With Rng
                
                    If .Value < mi.Value Then Set mi = Rng
                    
                End With
                
            Next
            
            If mi = 9E+99 Then
                Exit For
            Else
                mi.Interior.Color = mi.Value
                mi = Empty
            End If
            
        Next i
    
End Sub

这段代码可以实现手绘的效果

 

 

此方法是先将图片信息换算成EXCEL识别的color值后,写入ilist数组(ilist 数组从np得到),然后一次性写入EXCEL。

再调用excel加载项中的vba过程为单元格上色。

相比前者一个单元格一个单元格赋值调色 快指数级。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值