Are there any high-quality, programmatic solutions for converting a jpeg with an opaque background to a png with a transparent background?
The common use case here is a user uploading a jpeg logo with a white/color background. It's (fairly) simple to switch the white pixels to transparent ones, but this leaves aliasing artifacts. An ideal solution wou开发者_如何学编程ld essentially "undo" the aliasing (given a known background color). At a minimum, the solution must beat the bg_removal script for ImageMagick (http://imagemagick.org/Usage/scripts/bg_removal).
The "Color to Alpha" algorithm in GIMP looks like it does a pretty good job. The source is GPL and can be found here. A demonstration of what the GIMP algorithm does with something like a logo is here, and the GIMP manual page for Color-to-Alpha is here.
It looks like the most straightforward way to do this programmatically would be to use GIMP batch mode.
As promised, here's a working solution for the common white --> alpha use case. This is running on an Ubuntu 10.04.1 LTS server with the standard GIMP installation (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')
I execute this code from Python (within Django) using the subprocess module (code_as_string is the above code as a string, with input_filepath inserted:
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())
精彩评论