Fixed some issues with icon generation.
This commit is contained in:
parent
0cb12bd2f5
commit
19c8f08c61
3 changed files with 84 additions and 36 deletions
|
|
@ -254,7 +254,7 @@ def _save(im, fp, filename, check=0):
|
||||||
ppm = tuple(map(lambda x: int(x * 39.3701), dpi))
|
ppm = tuple(map(lambda x: int(x * 39.3701), dpi))
|
||||||
|
|
||||||
stride = ((im.size[0]*bits+7)//8+3) & (~3)
|
stride = ((im.size[0]*bits+7)//8+3) & (~3)
|
||||||
header = 64 #108 if im.mode == 'RGBA' else 40 # or 64 for OS/2 version 2
|
header = 108 if im.mode == 'RGBA' else 40 # or 64 for OS/2 version 2
|
||||||
offset = 14 + header + colors*4
|
offset = 14 + header + colors*4
|
||||||
image = stride * im.size[1]
|
image = stride * im.size[1]
|
||||||
|
|
||||||
|
|
@ -265,14 +265,14 @@ def _save(im, fp, filename, check=0):
|
||||||
|
|
||||||
# bitmap header
|
# bitmap header
|
||||||
fp.write(b"BM" + # file type (magic)
|
fp.write(b"BM" + # file type (magic)
|
||||||
o32(offset+image) + # file size
|
o32(offset+image+16) + # file size
|
||||||
o32(0) + # reserved
|
o32(0) + # reserved
|
||||||
o32(offset)) # image data offset
|
o32(offset+16)) # image data offset
|
||||||
|
|
||||||
width,height = im.size
|
width,height = im.size
|
||||||
|
|
||||||
# bitmap info header
|
# bitmap info header
|
||||||
fp.write(o32(header) + # info header size
|
fp.write(o32(header+16) + # info header size
|
||||||
o32(width) + # width
|
o32(width) + # width
|
||||||
o32(height) + # height
|
o32(height) + # height
|
||||||
o16(1) + # planes
|
o16(1) + # planes
|
||||||
|
|
@ -281,28 +281,28 @@ def _save(im, fp, filename, check=0):
|
||||||
o32(image) + # size of bitmap
|
o32(image) + # size of bitmap
|
||||||
o32(ppm[0]) + o32(ppm[1]) + # resolution
|
o32(ppm[0]) + o32(ppm[1]) + # resolution
|
||||||
o32(colors) + # colors used
|
o32(colors) + # colors used
|
||||||
o32(colors) + # colors important
|
o32(colors) # colors important
|
||||||
o32(red_mask) + # red channel ma
|
#o32(red_mask) + # red channel ma
|
||||||
o32(green_mask) + # green channel mask
|
#o32(green_mask) + # green channel mask
|
||||||
o32(blue_mask) + # blue channel mask
|
#o32(blue_mask) + # blue channel mask
|
||||||
o32(alpha_mask)
|
#o32(alpha_mask)
|
||||||
)
|
)
|
||||||
# This was commented out because although it works, some
|
# This was commented out because although it works, some
|
||||||
# decoders do not support images with a BI_BITFIELDS compression
|
# decoders do not support images with a BI_BITFIELDS compression
|
||||||
#
|
#
|
||||||
#if im.mode == 'RGBA':
|
if im.mode == 'RGBA':
|
||||||
# fp.write(o32(red_mask) + # red channel mask
|
fp.write(o32(red_mask) + # red channel mask
|
||||||
# o32(green_mask) + # green channel mask
|
o32(green_mask) + # green channel mask
|
||||||
# o32(blue_mask) + # blue channel mask
|
o32(blue_mask) + # blue channel mask
|
||||||
# o32(alpha_mask) + # alpha channel mask
|
o32(alpha_mask) + # alpha channel mask
|
||||||
# 'BGRs' + # Color Space
|
'BGRs' + # Color Space
|
||||||
# o8(0)*0x24 + # ciexyztriple color space endpoints
|
o8(0)*0x24 + # ciexyztriple color space endpoints
|
||||||
# o32(0) + # red gamma
|
o32(0) + # red gamma
|
||||||
# o32(0) + # green gamma
|
o32(0) + # green gamma
|
||||||
# o32(0) # blue gamma
|
o32(0) # blue gamma
|
||||||
# )
|
)
|
||||||
|
|
||||||
fp.write(bytearray(header - 40 - 4))
|
fp.write(bytearray(16))
|
||||||
|
|
||||||
if im.mode == "1":
|
if im.mode == "1":
|
||||||
for i in (0, 255):
|
for i in (0, 255):
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ def get_data(im):
|
||||||
dib = dib[:40]
|
dib = dib[:40]
|
||||||
bmp_f.seek(offset)
|
bmp_f.seek(offset)
|
||||||
data = bytearray(bmp_f.read())
|
data = bytearray(bmp_f.read())
|
||||||
data = dib+data[24:] + bytearray(24)
|
data = dib+data
|
||||||
else:
|
else:
|
||||||
data = bytearray(s.read())
|
data = bytearray(s.read())
|
||||||
|
|
||||||
|
|
@ -330,6 +330,31 @@ def _save(image, fp, filename, check=0):
|
||||||
rawmode, bits, colors = SAVE[im.mode]
|
rawmode, bits, colors = SAVE[im.mode]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise IOError("cannot write mode %s as BMP" % im.mode)
|
raise IOError("cannot write mode %s as BMP" % im.mode)
|
||||||
|
matte_data = bytearray()
|
||||||
|
if im.format == 'BMP':
|
||||||
|
|
||||||
|
#write matte data. Taken from imagemagick
|
||||||
|
scanline_pad = (((im.size[0]+31) & ~31)-im.size[0]) >> 3
|
||||||
|
row_len = im.size[0]*4
|
||||||
|
for y in reversed(xrange(im.size[1])):
|
||||||
|
d = data[40:]
|
||||||
|
#BGRA
|
||||||
|
row_pixels = d[row_len*y:row_len*y+row_len]
|
||||||
|
bit=0
|
||||||
|
byte=0
|
||||||
|
for x in xrange(im.size[0]):
|
||||||
|
p=row_pixels[x]
|
||||||
|
|
||||||
|
byte<<=1
|
||||||
|
bit+=1
|
||||||
|
if bit == 8:
|
||||||
|
matte_data+=o8(byte)
|
||||||
|
bit=0
|
||||||
|
byte=0
|
||||||
|
if not bit == 0:
|
||||||
|
matte_data+=o8(byte<<(8-bit))
|
||||||
|
for i in xrange(scanline_pad):
|
||||||
|
matte_data+=o8(0)
|
||||||
|
|
||||||
fp.write(o8(im.size[0]) + # width
|
fp.write(o8(im.size[0]) + # width
|
||||||
o8(im.size[1]) + # height
|
o8(im.size[1]) + # height
|
||||||
|
|
@ -337,17 +362,43 @@ def _save(image, fp, filename, check=0):
|
||||||
o8(0) + # reserved
|
o8(0) + # reserved
|
||||||
o16(1) + # planes
|
o16(1) + # planes
|
||||||
o16(bits) + # depth
|
o16(bits) + # depth
|
||||||
o32(len(data)) + # size of image in bytes
|
o32(len(data+matte_data)) + # size of image in bytes
|
||||||
o32(current_offset) # offset
|
o32(current_offset) # offset
|
||||||
|
|
||||||
)
|
)
|
||||||
current_offset += len(data)
|
current_offset += len(data+matte_data)
|
||||||
|
|
||||||
for im in images:
|
for im in images:
|
||||||
|
|
||||||
data = get_data(im)
|
data = get_data(im)
|
||||||
fp.write(data)
|
fp.write(data)
|
||||||
|
|
||||||
|
if im.format == 'BMP':
|
||||||
|
|
||||||
|
#write matte data. Taken from imagemagick
|
||||||
|
scanline_pad = (((im.size[0]+31) & ~31)-im.size[0]) >> 3
|
||||||
|
row_len = im.size[0]*4
|
||||||
|
for y in reversed(xrange(im.size[1])):
|
||||||
|
d = data[40:]
|
||||||
|
#BGRA
|
||||||
|
row_pixels = d[row_len*y:row_len*y+row_len]
|
||||||
|
bit=0
|
||||||
|
byte=0
|
||||||
|
for x in xrange(im.size[0]):
|
||||||
|
p=row_pixels[x]
|
||||||
|
|
||||||
|
byte<<=1
|
||||||
|
bit+=1
|
||||||
|
if bit == 8:
|
||||||
|
fp.write(o8(byte))
|
||||||
|
bit=0
|
||||||
|
byte=0
|
||||||
|
if not bit == 0:
|
||||||
|
fp.write(o8(byte<<(8-bit)))
|
||||||
|
for i in xrange(scanline_pad):
|
||||||
|
fp.write(o8(0))
|
||||||
|
|
||||||
|
|
||||||
fp.flush()
|
fp.flush()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
21
pe.py
21
pe.py
|
|
@ -4,7 +4,7 @@ from cStringIO import StringIO
|
||||||
|
|
||||||
from ico_plugin import *
|
from ico_plugin import *
|
||||||
|
|
||||||
def resize(image, size):
|
def resize(image, size, format=None):
|
||||||
output = StringIO()
|
output = StringIO()
|
||||||
back = Image.new('RGBA', size, (0,0,0,0))
|
back = Image.new('RGBA', size, (0,0,0,0))
|
||||||
image.thumbnail(size, Image.ANTIALIAS)
|
image.thumbnail(size, Image.ANTIALIAS)
|
||||||
|
|
@ -14,7 +14,8 @@ def resize(image, size):
|
||||||
else:
|
else:
|
||||||
offset[0] = back.size[0]/2-image.size[0]/2
|
offset[0] = back.size[0]/2-image.size[0]/2
|
||||||
back.paste(image, tuple(offset))
|
back.paste(image, tuple(offset))
|
||||||
back.save(output, image.format)
|
format = format or image.format
|
||||||
|
back.save(output, format)
|
||||||
contents = output.getvalue()
|
contents = output.getvalue()
|
||||||
output.close()
|
output.close()
|
||||||
return contents
|
return contents
|
||||||
|
|
@ -1252,20 +1253,16 @@ class PEFile(Printable):
|
||||||
g_entry = group_header.entries[0]
|
g_entry = group_header.entries[0]
|
||||||
|
|
||||||
icon = Image.open(icon_path)
|
icon = Image.open(icon_path)
|
||||||
i_data = resize(icon, (g_entry.Width.value, g_entry.Height.value))
|
i_data = resize(icon, (g_entry.Width.value, g_entry.Height.value), format='ico')
|
||||||
s = StringIO()
|
|
||||||
s.write(i_data)
|
|
||||||
s.seek(0)
|
|
||||||
|
|
||||||
icon = Image.open(s)
|
new_icon_size = len(i_data)
|
||||||
s2 = StringIO()
|
|
||||||
icon.save(s2, 'ico')
|
|
||||||
new_icon_size = s2.tell()
|
|
||||||
s2.seek(0)
|
|
||||||
icon_file_size = g_entry.DataSize.value+group_header.size+g_entry.size+2
|
icon_file_size = g_entry.DataSize.value+group_header.size+g_entry.size+2
|
||||||
|
|
||||||
#9662 is the exact length of the icon in nw.exe
|
#9662 is the exact length of the icon in nw.exe
|
||||||
icon_data = bytearray(s2.read()) + bytearray(icon_file_size-new_icon_size)
|
extra_size = icon_file_size-new_icon_size
|
||||||
|
if extra_size < 0:
|
||||||
|
extra_size = 0
|
||||||
|
icon_data = bytearray(i_data) + bytearray(extra_size)
|
||||||
|
|
||||||
icon_header = IconHeader.parse_from_data(icon_data, absolute_offset=0)
|
icon_header = IconHeader.parse_from_data(icon_data, absolute_offset=0)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue