Fix transparency missing with indexed color

This commit is contained in:
Mike L 2025-04-30 00:14:20 +02:00
parent b4e2de09b2
commit d57a50bedd
Signed by: mikeslab
GPG key ID: 48CCD1768D862D40
3 changed files with 35 additions and 5 deletions

View file

@ -14,7 +14,15 @@ def scaleImage(img, scale):
def readCUR(f, width=-1.0, height=-1.0): def readCUR(f, width=-1.0, height=-1.0):
frameImage = Image.open(f, formats=['cur', 'ico']).convert('RGBA') frameImage = Image.open(f, formats=['cur', 'ico'])
if (frameImage.mode == 'P'):
palette = list(frameImage.palette.getdata()[1])
for i in range(4, len(palette), 4):
if sum(palette[i:i + 3]) == 0:
break
palette[i + 3] = 255
frameImage.putpalette(palette, 'BGRA')
frameImage = frameImage.convert('RGBA')
if (width, height) == (-1.0, -1.0): if (width, height) == (-1.0, -1.0):
return frameImage, (float(frameImage.width), float(frameImage.height)) return frameImage, (float(frameImage.width), float(frameImage.height))
if -1 in (width, height): if -1 in (width, height):

View file

@ -46,6 +46,16 @@ def analyzeANIFile(filePath):
nowSize += subChunkSize nowSize += subChunkSize
return {"code":0,"msg":frameList,"frameRate":frameRate} return {"code":0,"msg":frameList,"frameRate":frameRate}
def CURPaletteFix(image):
# type: (Image.ImageFile.ImageFile) -> None
if (image.mode == 'P'):
palette = list(image.palette.getdata()[1])
for i in range(4, len(palette), 4):
if sum(palette[i:i + 3]) == 0:
break
palette[i + 3] = 255
image.putpalette(palette, 'BGRA')
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) < 2: if len(sys.argv) < 2:
logging.fatal("Usage:python ani2gif.py <inputFile> <outputFile,Option>") logging.fatal("Usage:python ani2gif.py <inputFile> <outputFile,Option>")
@ -55,8 +65,9 @@ if __name__ == '__main__':
if res["code"] == 0: if res["code"] == 0:
logging.info('ANI文件分析完成帧提取完成') logging.info('ANI文件分析完成帧提取完成')
for frame in res["msg"]: for frame in res["msg"]:
frameImage = Image.open(io.BytesIO(frame),formats=['CUR']).convert('RGBA') frameImage = Image.open(io.BytesIO(frame),formats=['CUR'])
GIFframes.append(frameImage) CURPaletteFix(frameImage)
GIFframes.append(frameImage.convert('RGBA'))
if(len(sys.argv) >= 3): if(len(sys.argv) >= 3):
GIFframes[0].save(sys.argv[2],format="GIF",save_all=True, append_images=GIFframes[1:], optimize=False, duration=res["frameRate"], loop=0, transparency=0, disposal=2) GIFframes[0].save(sys.argv[2],format="GIF",save_all=True, append_images=GIFframes[1:], optimize=False, duration=res["frameRate"], loop=0, transparency=0, disposal=2)
else: else:

View file

@ -46,6 +46,16 @@ def analyzeANIFile(filePath):
nowSize += subChunkSize nowSize += subChunkSize
return {"code":0,"msg":frameList,"frameRate":frameRate} return {"code":0,"msg":frameList,"frameRate":frameRate}
def CURPaletteFix(image):
# type: (Image.ImageFile.ImageFile) -> None
if (image.mode == 'P'):
palette = list(image.palette.getdata()[1])
for i in range(4, len(palette), 4):
if sum(palette[i:i + 3]) == 0:
break
palette[i + 3] = 255
image.putpalette(palette, 'BGRA')
if __name__ == '__main__': if __name__ == '__main__':
OUTPUT_SIZE = (48,48) OUTPUT_SIZE = (48,48)
if len(sys.argv) < 2: if len(sys.argv) < 2:
@ -57,8 +67,9 @@ if __name__ == '__main__':
logging.info('ANI文件分析完成帧提取完成') logging.info('ANI文件分析完成帧提取完成')
output = Image.new("RGBA", (OUTPUT_SIZE[0], OUTPUT_SIZE[1] * len(res["msg"]))) output = Image.new("RGBA", (OUTPUT_SIZE[0], OUTPUT_SIZE[1] * len(res["msg"])))
for frameIndex in range(len(res["msg"])): for frameIndex in range(len(res["msg"])):
frameImage = Image.open(io.BytesIO(res["msg"][frameIndex]),formats=['cur']).convert('RGBA') frameImage = Image.open(io.BytesIO(res["msg"][frameIndex]),formats=['cur'])
extracted_frame = frameImage.resize(OUTPUT_SIZE) CURPaletteFix(frameImage)
extracted_frame = frameImage.convert('RGBA').resize(OUTPUT_SIZE)
position = (0, OUTPUT_SIZE[0] * frameIndex) position = (0, OUTPUT_SIZE[0] * frameIndex)
output.paste(extracted_frame, position) output.paste(extracted_frame, position)
if(len(sys.argv) >= 3): if(len(sys.argv) >= 3):