Recipe: Image transparent background
Sometimes you need to remove a simple background from an image. This is why we created a handy tool for quick transparency restoring or to make images and icons usable. This is a process that works by color selection and tolerance.
The recipe uses ImageMagick to add a transparent background to images by using a color from one corner of the image. The same color around the image will be made transparent up to a given tolerance percentage threshold.
Anti alias will fix rough edges. And lastly the filename tag will be added to the output file and placed next to the source file.
Download the recipe from the extended collection here:
https://magnetron.app/recipes/image-transparent-background
For Windows & macOS
You can run this recipe with a magnetron.app license key.
With magnetron.dev you can also use the source to create your own custom processes.
Take a closer look at the source below
(added July 2023)
header={
"recipe_version": "1.6",
"title": "Make image background transparent",
"description": "Convert images to a transparent background by using a color from one corner",
"tags": "ImageMagick,image,transparent",
"chef": "BeatRig",
"dependencies": "identify,convert",
"instructions": "Drop image files here and run this recipe to select the background detection settings",
"type": "default",
"os": "windows,macOS",
"palette": "Mint Cream",
"spice": "BQ==:G+Hy36kJcnQQYYavb/JV2Il6eCYr6h4hRJHCF9rRbhX5BcazL6cuTgUMdz0xA50VWA5PmmV0Q7aWkiUtNFtbk991l+t0e8IBXMReMIT1GNjnZZDv7n2YRAo0xcSQbY0ixjG6LLH4wGKnspKAoA/v69iLn6N2IH0XzIZwTGdHSo4=",
"flavour": "5gnchER9IDp3Qba1ew9cEMnTc+pUXHxXhJg7iMtxZrEmHReJsUclezzYzLSoirkfGsOmvQOGPrV976j4i9uN/04nmzQXjeMYmQOLk2tvuwGSv9ht0tMYtIP+yuWwL6cUA7Qh11eJAIrOO04B7horG/krlUQJ68cMVZu7jB2vvhA=",
"time": 1694301146,
"core_version": "0.5.7",
"magnetron_version": "1.0.261",
"functions": "main,onAbout",
"uuid": "7ebe4cd6eee6474c8c1190d380f4c630"
};
//----------------------------------------------------------------------------
// o7 based on https://github.com/hackerb9/mktrans/blob/master/mktrans
function main()
{
CheckInstalled();
var antialias_items = ["Anti-alias","Anti-alias (fast)","No anti-alias"];
var corner_items = ["Top-Left","Top-Right","Bottom-Left","Bottom-Right"];
var corner = corner_items[0];
var fuzz = "20";
var antialias = antialias_items[0];
var tag = "-transparent";
var files = getFiles();
if (files.length <= 0)
abort("drop a file to process first");
for (var i = 0; i < files.length; i++)
{
filename = files[i].path;
pathInfo = getPathInfo(filename);
setMainMessage("processing " + pathInfo.basename);
setProgress((i+0.5) / files.length * 100.);
var dialog_width = 500;
var form = {
"mainlabel" : {
"type" : "label",
"label" : "Add transparancy from a specific background corner color to\n" + pathInfo.basename,
"bounds" : {
"x" : 5,
"w" : dialog_width,
"h" : 60,
"y" : 5,
}
},
"cornerlabel" : {
"type" : "label",
"label" : "The sample color corner",
"bounds" : {
"x" : 5,
"w" : dialog_width/2,
}
},
"corner" : {
"type" : "combobox",
"default" : corner,
"items" : corner_items,
"label" : "Sample color corner",
"bounds" : {
"x" : dialog_width/2,
"y" : -1,
"w" : dialog_width/2,
}
},
"fuzzlabel" : {
"type" : "label",
"label" : "Color tolerance",
"bounds" : {
"x" : 5,
"w" : dialog_width/2
}
},
"fuzz" : {
"type" : "slider",
"value": 30,
"range" : {
"min" : 0,
"max" : 100,
"interval" : 1,
"decimals": 0
},
"label" : "color % tolerance:",
"bounds" : {
"x" : dialog_width/2,
"y" : -1,
"w" : dialog_width/2
}
},
"antialiaslabel" : {
"type" : "label",
"label" : "anti-alias type",
"bounds" : {
"x" : 5,
"w" : dialog_width/2
}
},
"antialias" : {
"type" : "combobox",
"default" : antialias,
"items" : antialias_items,
"label" : "anti-alias types:",
"bounds" : {
"x" : dialog_width/2,
"y" : -1,
"w" : dialog_width/2
}
},
"tag" : {
"type" : "textedit",
"default" : tag,
"label" : "add file name tag:",
"bounds" : {
"x" : dialog_width/2,
"y" : -1,
"w" : dialog_width/2
}
},
"okay" : {
"type" : "button",
"label" : "okay",
"returns" : 1
},
"cancel" : {
"type" : "button",
"label" : "cancel",
"returns" : 0
}
};
form_out = dialog(form);
if (form_out.cancel)
abort("Cancelled");
corner = form_out.corner;
fuzz = form_out.fuzz;
antialias = form_out.antialias;
tag = form_out.tag;
outfile = pathInfo.folder + pathInfo.sep + pathInfo.basename + form_out.tag + ".png";
var wah = cmd("identify", ["-format", "%w,%h", filename]);
var dimensions = wah.split(",");
echo("dimensions:" + dimensions[0] + "x" + dimensions[1]);
var x = 0;
var y = 0;
if (form_out.corner == corner_items[1])
x = dimensions[0];
if (form_out.corner == corner_items[2])
y = dimensions[1];
if (form_out.corner == corner_items[3])
{
x = dimensions[0];
y = dimensions[1];
}
pixelcomma = x + "," + y;
pixelplus = "+" + x + "+" + y;
var pflag = false; // false for 1 pixel border
// Get color of pixel
var color = cmd("convert", [filename, "-format", "%[pixel:p{" + pixelcomma + "}]", "info:-"]);
// check if starts with rgba and ends with ,0)
if (color.substring(0, 4) == "rgba" && color.substring(color.length - 3, color.length) == ",0)")
color = color.substring(0, color.length - 3) + ",1)"; // if so replace end with ,1)
if (color == "none")
abort (filename + " pixel at " + pixelcomma + " completely transparent. Cannot floodfill");
echo(color);
var options=[filename];
if (pflag == false) // Add a 1 pixel border so we'll fill from the bottom and sides as well.
{
options.push("-bordercolor");
options.push(color);
options.push("-border");
options.push("1");
}
// In a new stack, make a copy of the image
options.push("(");
options.push("+clone");
// [copy] floodfill with transparency ("none") starting at top-left
options.push("-fuzz");
options.push(form_out.fuzz + "%");
options.push("-fill");
options.push("none");
options.push("-floodfill");
options.push(pixelplus);
options.push(color);
// [copy] extract just the transparency (alpha channel)
options.push("-alpha");
options.push("extract");
if (form_out.antialias != antialias_items[2])
{
if (form_out.antialias == antialias_items[1])
{
// [copy] blow up the alpha channel so we can do sub-pixel morphology
options.push("-geometry");
options.push("200%");
// [copy] blur the alpha channel to make it antialiased
options.push("-blur");
options.push("0x0.5");
// [copy] shrink the region that is opaque by half a pixel.
options.push("-morphology");
options.push("erode");
options.push("square:1");
// [copy] scale the alpha channel back to normal size.
options.push("-geometry");
options.push("50%");
}
else // speedy antialias
{
// [copy] blur the alpha channel to make it antialiased
options.push("-blur");
options.push("0x1");
// [copy] only antialias inside the figure (<50% opacity becomes 0%)
options.push("-level");
options.push("50%,100%");
}
}
// [copy] end the stack.
options.push(")");
// Compose the original image and the copy's alpha channel.
options.push("-compose");
options.push("CopyOpacity");
options.push("-composite");
if (pflag == false) // Remove the 1 pixel border we added
{
options.push("-shave");
options.push("1");
}
options.push(outfile);
echo("convert " + objectToString(options));
echo(cmd("convert", options));
setProgress((i+1) / files.length * 100.);
if (isCanceled())
abort("Canceled");
}
setMainMessage("finished");
}
function onAbout()
{
dialog(header.title, header.description, "i");
}
//----------------------------------------------------------------------------
function CheckInstalled()
{
var cmds = header.dependencies.split(",");
for (i = 0; i < cmds.length; i++)
{
var install_cmd = cmds[i];//"convert";
var cmd_path = getAllowedApps(install_cmd);
if (cmd_path.length <= 0)
abort("ImageMagick " + install_cmd + " not installed");
}
}