Convert Transparent Png to Jpg with Non-Black Background Color

Convert Transparent PNG to JPG with Non-Black Background Color

// Assumes myImage is the PNG you are converting
using (var b = new Bitmap(myImage.Width, myImage.Height)) {
b.SetResolution(myImage.HorizontalResolution, myImage.VerticalResolution);

using (var g = Graphics.FromImage(b)) {
g.Clear(Color.White);
g.DrawImageUnscaled(myImage, 0, 0);
}

// Now save b as a JPEG like you normally would
}

Convert PNG with transparency to JPG

The problem with converting PNG to JPG is when the PNG has transparency. JPG does not allow transparency and any transparent areas will show what color is underneath the transparency, which is often black. So you should use -flatten to properly do that conversion. But you should specify -background somecolor before -flatten, if you do not want the default background color. GIF only allows binary transparency -- fully transparent or fully opaque. PNG allows 8-bit transparency (partial transparent). I know of no significant issues using -background xx -flatten when converting PNG or GIF to JPG. However, the background color you use will change the appearance in transparent areas from that of the underneath color. Here is what is happening:

Input:

Sample Image

Turn alpha off:

convert google.png -alpha off google_aoff.jpg

Sample Image

The stripes are from the underneath color below the alpha channel.

Alpha Channel (nicely antialiased):

convert google.png -alpha extract google_alpha.jpg

Sample Image

Simple Flatten (default background is white):

convert google.png -flatten google_flatten.jpg

Sample Image

Flatten with black background:

convert google.png -background black -flatten google_flatten_black.jpg

Sample Image

Often one will reprocess the original transparent PNG image so that it has some constant color underneath the alpha channel so that later one can remove the alpha channel and not have odd colors showing. It will look the very same as the original PNG.

convert google.png -background white -alpha background google_bg_white.png

Sample Image

However, if you simply remove the alpha channel the JPG will show aliasing since only the fully transparent pixels' background colors were changed to white. You have a nice clean background, but the image is still aliased (as it was in the original when the alpha channel was remove).

convert google_bg_white.png google_bg_white.jpg

Sample Image

So one still needs to flatten the result, so that the antialiasing of the alpha channel will smoothly blend the colors near the boundaries.

convert google_bg_white.png -flatten google_bg_white_flatten.jpg

Sample Image

An alternate method to -flatten is to use -alpha remove, which is discussed http://www.imagemagick.org/Usage/masking/#alpha_remove. So starting with the original PNG, we do

convert google.png -background white -alpha remove google_alpharemoveoff.jpg

Sample Image

The result is the same as -background white -flatten. We do not need the -alpha off mentioned in the reference, since JPG does not support any alpha channel. The reference says this is more efficient and is the preferred method.

Converting transparent png to jpg powershell

Based on the answer from Convert Transparent PNG to JPG with Non-Black Background Color

$files = Get-ChildItem "C:\Pictures\test" -Filter *.png -file -Recurse | 
foreach-object {

$Source = $_.FullName
$test = [System.IO.Path]::GetDirectoryName($source)
$base= $_.BaseName+".jpg"
$basedir = $test+"\"+$base
Write-Host $basedir
Add-Type -AssemblyName system.drawing
$imageFormat = "System.Drawing.Imaging.ImageFormat" -as [type]
$image = [drawing.image]::FromFile($Source)
# $image.Save($basedir, $imageFormat::jpeg) Don't save here!

# Create a new image
$NewImage = [System.Drawing.Bitmap]::new($Image.Width,$Image.Height)
$NewImage.SetResolution($Image.HorizontalResolution,$Image.VerticalResolution)

# Add graphics based on the new image
$Graphics = [System.Drawing.Graphics]::FromImage($NewImage)
$Graphics.Clear([System.Drawing.Color]::White) # Set the color to white
$Graphics.DrawImageUnscaled($image,0,0) # Add the contents of $image

# Now save the $NewImage instead of $image
$NewImage.Save($basedir,$imageFormat::Jpeg)

# Uncomment these two lines if you want to delete the png files:
# $image.Dispose()
# Remove-Item $Source
}

Replace transparency in PNG image with white background

This works for me:

convert -flatten img1.png img1-white.png

Documentation references:

  • -flatten command-line option
  • -layers command-line option (-flatten is equivalent to -layers flatten)

Override transparency color when converting transparent PNG to JPG

You can create an ImageList to be able to put a white image with the same size as your original image UNDER the transparent picture. If you flatten the ImageList down to an image, you get an image with the transparent color replaced by whatever the second image contained.

img_list = Magick::ImageList.new
img_list.read("my_png_file.png")
img_list.new_image(img_list.first.columns, img_list.first.rows) { self.background_color = "white" } # Create new "layer" with white background and size of original image
image = img_list.reverse.flatten_images

This works for me but could be optimized further, i guess.

Hope that helps!
Hendrik

How can I convert a JPEG image to a PNG one with transparent background?

Here is working, but slow solution. You can speed it up by using Bitmap.LockBits().

using (Image img = Image.FromFile(filename))
using (Bitmap bmp = new Bitmap(img))
{
for (int x = 0; x < img.Width; x++)
{
for (int y = 0; y < img.Height; y++)
{
Color c = bmp.GetPixel(x, y);
if (c.R == 255 && c.G == 255 && c.B == 255)
bmp.SetPixel(x, y, Color.FromArgb(0));
}
}
bmp.Save("out.png", ImageFormat.Png);
}

Convert transparent png in color to single color

The other answers was helpful and got me going, thanks a lot. I couldn't make them work though, not sure why. But I also found out that I wanted to keep the original alpha value of the pixels, rendering the edges smooth. This is what I came up with.

for (int x = 0; x < bitmap.Width; x++)
{
for (int y = 0; y < bitmap.Height; y++)
{
Color bitColor = bitmap.GetPixel(x, y);
//Sets all the pixels to white but with the original alpha value
bitmap.SetPixel(x, y, Color.FromArgb(bitColor.A, 255, 255, 255));
}
}

Here is a screen dump of the result magnified a few times (original on top):
alt text
(source: codeodyssey.se)



Related Topics



Leave a reply



Submit