我正试图从Windows中的文件中获取48x48或256x256图标,并且遇到了看似死路一条的东西。目前我在python中有一个HICON句柄(因为PySides QFileIconProvider只返回32x32图标),我想在pyside窗口中显示但是QPixmap.fromHICON / HBITMAP等函数没有实现,似乎也从源代码中删除了自Qt 4.8(?)。另外,我试图避免将图标保存到文件中。
那么,有没有什么方法可以将HICON或任何其他可以转换成其他东西的东西转换成任何类型的PySide对象?
编辑: 我一直在尝试简单地在python中重写来自WinHBITMAP函数的旧函数,但它并不是很好。我不确定我应该如何将src行转换为python,我也不知道如何更改QImage.scanLine()返回的内存缓冲区的值
for (int y=0; y<h; ++y) {
QRgb *dest = (QRgb *) image.scanLine(y);
const QRgb *src = (const QRgb *) (data + y * bytes_per_line);
for (int x=0; x<w; ++x) {
dest[x] = src[x] | mask;
}
}
目前我使用win32api从HICON创建PyCBITMAP并检索位列表。
for y in range(0, hIcon.height):
dest = i.scanLine(y)
src = bitmapbits[y*hIcon.widthBytes:(y*hIcon.widthBytes)+hIcon.widthBytes]
for x in range(0, hIcon.width):
dest[x] = bytes(ctypes.c_uint32(src[x] | 0))
这导致“ValueError:无法修改memoryview对象的大小”
可在此处找到该函数的来源:http://www.qtcentre.org/threads/19188-Converting-from-HBitmap-to-a-QPixmap?p=94747#post94747
答案 0 :(得分:2)
修正了它!
def iconToQImage(hIcon):
hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap(hdc, hIcon.width, hIcon.height)
hdc = hdc.CreateCompatibleDC()
hdc.SelectObject(hbmp)
win32gui.DrawIconEx(hdc.GetHandleOutput(), 0, 0, hIcon.hIcon, hIcon.width, hIcon.height, 0, None, 0x0003)
bitmapbits = hbmp.GetBitmapBits(True)
image = QtGui.QImage(bitmapbits, hIcon.width, hIcon.height, QtGui.QImage.Format_ARGB32_Premultiplied)
return image
答案 1 :(得分:1)
要进行这种设置有点困难但是从我读到的Python成像库(PIL)支持bitmap and ICO files并且downloads for Windows。假设您可以获取图标的文件名,可以使用PIL加载它,然后转移raw data to a QImage:
from PIL import Image
from PySide.QtGui import QImage, QImageReader, QLabel, QPixmap, QApplication
im = Image.open("my_image.png")
data = im.tostring('raw', 'RGBA')
app = QApplication([])
image = QImage(data, im.size[0], im.size[1], QImage.Format_ARGB32)
pix = QPixmap.fromImage(image)
lbl = QLabel()
lbl.setPixmap(pix)
lbl.show()
app.exec_()
然后使用您需要执行的任何QImage
操作。
答案 2 :(得分:0)
虽然@egs0 的回答是准确的,但尝试显示输出可能会导致问题,因为 QLabel
不能很好地处理位图。要解决这些问题,请将结果转换为另一种图像格式。
import win32ui
import win32gui
# Doesn't matter which library. Qt5 should work just as well.
from PySide6 import QtGui, QtCore
def iconToQImage(hIcon, width, height, im_format="PNG"):
hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap(hdc, width, height)
hdc = hdc.CreateCompatibleDC()
hdc.SelectObject(hbmp)
win32gui.DrawIconEx(hdc.GetHandleOutput(), 0, 0, hIcon, width, height, 0, None, 0x0003)
bitmapbits = hbmp.GetBitmapBits(True)
image = QtGui.QImage(bitmapbits, width, height, QtGui.QImage.Format_ARGB32_Premultiplied)
# Write to and then load from a buffer to convert to PNG.
buffer = QtCore.QBuffer()
buffer.setOpenMode(QtCore.QIODevice.ReadWrite)
image.save(buffer, im_format)
image.loadFromData(buffer.data(), im_format)
# Use QtGui.Pixmap.fromImage() to get a pixmap instead.
return image
还可以使用以下函数获取图标的大小,改编自 here:
def getIconSize(HIcon):
info = win32gui.GetIconInfo(HIcon)
if info[4]: # Icon has color plane.
bmp = win32gui.GetObject(info[4])
width = bmp.bmWidth
height = bmp.bmHeight
else: # Icon has no colour plane, image data stored in mask.
bmp = win32gui.GetObject(info[3])
width = bmp.width
height = bmp.height // 2 # A monochrome icon contains image and XOR mask in the hbmMask.
info[3].close()
info[4].close()
return width, height