有没有高质量的程序化解决方案可以将具有不透明背景的JPEG转换为具有透明背景的PNG?

6

这里的常见用例是用户上传具有白色/彩色背景的jpeg标志。将白色像素转换为透明像素(相对)简单,但这会留下混叠伪影。理想的解决方案本质上应该“撤消”混叠伪影(在已知背景颜色的情况下)。至少,这个解决方案必须胜过ImageMagick的bg_removal脚本(http://imagemagick.org/Usage/scripts/bg_removal)。


1
我不确定你所指的“别名伪影”是什么意思。也许你可以包含一张小图片来演示。 - Brent Bradburn
4
他所指的混叠现象源于一个事实,特别是在物体边缘处,像素的颜色是背景颜色和物体颜色的混合。 - Ken Wayne VanderLinde
@nobar:(反)混叠伪影是非常常见的。看到OP的问题以及他提到ImageMagick和你不知道什么是混叠伪影,我怀疑你能否帮助他;) GIYF - SyntaxT3rr0r
2个回答

2
"GIMP中的“颜色转透明”算法看起来做得很好。源代码是GPL,并且可以在这里找到。GIMP算法对于像标志这样的东西所做的演示可以在这里找到,而Color-to-Alpha的GIMP手册页面可以在这里找到。

从程序角度来看,最直接的方法似乎是使用GIMP批处理模式。"


初始测试看起来令人印象深刻,看看一个非常棘手的测试案例的前后对比:白色背景JPG格式 --> 透明背景PNG格式 - Jeremy Lewis
哇,这是一个棘手的案例。字母已经变成半透明了,但至少抗锯齿效果看起来很好! - Brent Bradburn
我增加了一个额外的步骤,即“加倍”剩余图像,以帮助消除字母透明度,不久将发布完整的GIMP Python脚本+如何执行。感谢您启动了我正确的方向。 - Jeremy Lewis

1

如承诺,这里是常见的白色 --> alpha 使用情况的解决方案。此解决方案正在运行在一个 Ubuntu 10.04.1 LTS 服务器上,使用标准的 GIMP 安装(2.6.8)。

from gimpfu import *

def run(input_filepath):
    image = pdb.gimp_file_load(input_filepath, input_filepath)
    image.disable_undo()
    layer = image.active_layer
    if not layer.is_rgb:
        pdb.gimp_image_convert_rgb(image)

    white = gimpcolor.RGB(1.0, 1.0, 1.0, 1.0)
    bg_color = pdb.gimp_image_pick_color(image, layer, 0, 0, True, False, 0)
    if bg_color == white:
        pdb.plug_in_colortoalpha(image, layer, bg_color)
        layer_copy = layer.copy()
        image.add_layer(layer_copy)
        image.merge_visible_layers(CLIP_TO_IMAGE)

    pdb.file_png_save_defaults(image, image.active_layer, input_filepath, input_filepath)

run('%(input_filepath)s')

我使用subprocess模块从Python(在Django中)执行此代码(code_as_string是上面的代码作为字符串,其中插入了input_filepath:

gimp_args = (settings.PATH_TO_GIMP, 
    '-i', 
    '--batch-interpreter=python-fu-eval', 
    '-b', code_as_string,
    '-b', 'from gimpfu import pdb; pdb.gimp_quit(True)')

environ = os.environ.copy()
environ['GIMP2_DIRECTORY'] = settings.PATH_TO_GIMP_DIR
p = subprocess.Popen(gimp_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=environ)
rc = p.wait()
if rc:
    logging.error(p.stdout.read())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接