我使用此方法调整png图像的大小:
Method for converting PNGs to premultiplied alpha
但这张照片仍然失去了透明度:
import Image, numpy
def resize(filename, img,height, width):
if filename.endswith(".png"):
img = img.convert('RGBA')
premult = numpy.fromstring(img.tostring(), dtype=numpy.uint8)
alphaLayer = premult[3::4] / 255.0
premult[::4] *= alphaLayer
premult[1::4] *= alphaLayer
premult[2::4] *= alphaLayer
img = Image.fromstring("RGBA", img.size, premult.tostring())
img = img.resize((height,width), Image.ANTIALIAS)
return img
这
至
答案 0 :(得分:3)
问题与链接问题无关,而是必须修补PIL,以便正确读取tRNS
PNG块。 PIL假定此块的单个值,但显示的此图像具有调色板中每个值的透明度描述。处理之后,解决问题很简单:将图像转换为'LA'
模式并调整大小:
import sys
from PIL import Image
img = Image.open(sys.argv[1])
pal = img.getpalette()
width, height = img.size
actual_transp = img.info['actual_transparency'] # XXX This will fail.
result = Image.new('LA', img.size)
im = img.load()
res = result.load()
for x in range(width):
for y in range(height):
t = actual_transp[im[x, y]]
color = pal[im[x, y]]
res[x, y] = (color, t)
result.resize((64, 64), Image.ANTIALIAS).save(sys.argv[2])
所以我们从这个转到:
针对这种特定情况的PIL补丁实际上非常简单。打开PIL/PngImagePlugin.py
,转到功能chunk_tRNS
,输入检查if
的{{1}}语句,然后检查im_mode == "P"
,然后添加行{ {1}}。
答案 1 :(得分:3)
这是一个更复杂的函数来调整大小(保持透明度):它允许您只使用新的宽度值,新的宽度和高度值或参考文件来获得新的大小。您也可以更改重新采样方法:
## PngResizeTransparency.py
#
## Resize PNG image by keeping the transparency
## thanks to https://stackoverflow.com/users/1453719/nicolas-barbey
#
## Use:
## - using a reference file to get new sizes:
# PNG_ResizeKeepTransparency(SourceFile, ResizedFile, RefFile ='YourRefFile.png')
## - using only the resized width:
# PNG_ResizeKeepTransparency(SourceFile, ResizedFile, new_width)
## - using resized width and hight:
# PNG_ResizeKeepTransparency(SourceFile, ResizedFile, new_width, new_height)
## - using resample mode: add param resample="NEAREST"/"BILINEAR"/"BICUBIC"/"ANTIALIAS"
from PIL import Image
def PNG_ResizeKeepTransparency(SourceFile, ResizedFile, new_width=0, new_height=0, resample="ANTIALIAS", RefFile =''):
# needs PIL
# Inputs:
# - SourceFile = initial PNG file (including the path)
# - ResizedFile = resized PNG file (including the path)
# - new_width = resized width in pixels; if you need % plz include it here: [your%] *initial width
# - new_height = resized hight in pixels ; default = 0 = it will be calculated using new_width
# - resample = "NEAREST", "BILINEAR", "BICUBIC" and "ANTIALIAS"; default = "ANTIALIAS"
# - RefFile = reference file to get the size for resize; default = ''
img = Image.open(SourceFile) # open PNG image path and name
img = img.convert("RGBA") # convert to RGBA channels
width, height = img.size # get initial size
# if there is a reference file to get the new size
if RefFile != '':
imgRef = Image.open(RefFile)
new_width, new_height = imgRef.size
else:
# if we use only the new_width to resize in proportion the new_height
# if you want % of resize please use it into new_width (?% * initial width)
if new_height == 0:
new_height = new_width*width/height
# split image by channels (bands) and resize by channels
img.load()
bands = img.split()
# resample mode
if resample=="NEAREST":
resample = Image.NEAREST
else:
if resample=="BILINEAR":
resample = Image.BILINEAR
else:
if resample=="BICUBIC":
resample = Image.BICUBIC
else:
if resample=="ANTIALIAS":
resample = Image.ANTIALIAS
bands = [b.resize((new_width, new_height), resample) for b in bands]
# merge the channels after individual resize
img = Image.merge('RGBA', bands)
# save the image
img.save(ResizedFile)
return
#######################################################
if __name__ == "__main__":
sFile = './autumn-png-leaf.png'
# resize using new width value (new height is calculated by keeping image aspect)
PNG_ResizeKeepTransparency(sFile, sFile[:-4]+'_resized.png', 400)
# resize using a reference file to get the new image dimension
PNG_ResizeKeepTransparency(sFile, sFile[:-4]+'_resized.png', RefFile = 'autumn-png-leaf_starry-night-van-gogh_fchollet_10.png')
答案 2 :(得分:1)
我已经解决了这个问题,不再需要来自mmgp的好的黑客攻击。 PIL现在将正确阅读并应用透明度。
https://github.com/d-schmidt/Pillow/commit/5baa1ac1b8d41fcedce7b12ed1c4a8e87b4851bc