Как превратить белый фон изображения в прозрачный фон? Кто-нибудь может сказать мне, как это сделать?
Как преобразовать изображение в прозрачное изображение в Java
Ответы (4)
Первый результат от Google таков:
Сделайте цвет прозрачным http://www.rgagnon.com/javadetails/java-0265.html
Это делает синюю часть изображения прозрачной, но я уверен, что вы можете адаптировать это, чтобы использовать вместо нее белый.
(подсказка: передать Color.WHITE функции makeColorTransparent вместо Color.BLUE)
Здесь нашел более полный и современный ответ: png">Как сделать цвет прозрачным в BufferedImage и сохранить как PNG
if ( ( rgb | 0xFF000000 ) == markerRGB ) {, вам нужно проверить, находится ли цвет в определенном диапазоне
- person tim_yates; 23.06.2010
Этот метод сделает фон прозрачным. Вам нужно передать изображение, которое вы хотите изменить, цвет и допуск.
final int color = ret.getRGB(0, 0);
final Image imageWithTransparency = makeColorTransparent(ret, new Color(color), 10);
final BufferedImage transparentImage = imageToBufferedImage(imageWithTransparency);
private static BufferedImage imageToBufferedImage(final Image image) {
final BufferedImage bufferedImage =
new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
final Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
return bufferedImage;
}
private static Image makeColorTransparent(final BufferedImage im, final Color color, int tolerance) {
int temp = 0;
if (tolerance < 0 || tolerance > 100) {
System.err.println("The tolerance is a percentage, so the value has to be between 0 and 100.");
temp = 0;
} else {
temp = tolerance * (0xFF000000 | 0xFF000000) / 100;
}
final int toleranceRGB = Math.abs(temp);
final ImageFilter filter = new RGBImageFilter() {
// The color we are looking for (white)... Alpha bits are set to opaque
public int markerRGBFrom = (color.getRGB() | 0xFF000000) - toleranceRGB;
public int markerRGBTo = (color.getRGB() | 0xFF000000) + toleranceRGB;
public final int filterRGB(final int x, final int y, final int rgb) {
if ((rgb | 0xFF000000) >= markerRGBFrom && (rgb | 0xFF000000) <= markerRGBTo) {
// Mark the alpha bits as zero - transparent
return 0x00FFFFFF & rgb;
} else {
// Nothing to do
return rgb;
}
}
};
final ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
return Toolkit.getDefaultToolkit().createImage(ip);
}
Вот мое решение. Этот фильтр удалит фон с любого изображения, если цвет фонового изображения находится в верхнем левом углу.
private static class BackgroundFilter extends RGBImageFilter{
boolean setUp = false;
int bgColor;
@Override
public int filterRGB(int x, int y, int rgb) {
int colorWOAlpha = rgb & 0xFFFFFF;
if( ! setUp && x == 0 && y == 0 ){
bgColor = colorWOAlpha;
setUp = true;
}
else if( colorWOAlpha == bgColor )
return colorWOAlpha;
return rgb;
}
}
В другом месте...
ImageFilter bgFilter = new BackgroundFilter();
ImageProducer ip = new FilteredImageSource(image.getSource(), bgFilter);
image = Toolkit.getDefaultToolkit().createImage(ip);
Я знаю, что этому вопросу более десяти лет и что некоторые ответы уже даны. Однако ни один из них не является удовлетворительным, если пиксели внутри изображения имеют тот же цвет, что и фон. Возьмем практический пример. Учитывая эти изображения:
оба имеют белый фон, но белый цвет также находится внутри вырезаемого изображения. Другими словами, белые пиксели снаружи двух вымпелов должны стать прозрачными, а те, что внутри, должны остаться такими, какие они есть. Добавьте к этому осложнение, заключающееся в том, что белый цвет фона не идеально белый (из-за сжатия jpeg), поэтому необходим допуск. Усложнить задачу можно фигурами не только выпуклыми, но и вогнутыми.
Я создал алгоритм на Java, который очень хорошо решает проблему, я протестировал его с помощью двух рисунков, показанных здесь. Следующий код относится к Java API Codename One (https://www.codenameone.com/javadoc/), но его можно перепрофилировать в Java SE API или реализовать на других языках. Главное понять суть.
/**
* Given an image with no transparency, it makes the white background
* transparent, provided that the entire image outline has a different color
* from the background; the internal pixels of the image, even if they have
* the same color as the background, are not changed.
*
* @param source image with a white background; the image must have an
* outline of a different color from background.
* @return a new image with a transparent background
*/
public static Image makeBackgroundTransparent(Image source) {
/*
* Algorithm
*
* Pixels must be iterated in the four possible directions: (1) left to
* right, for each row (top to bottom); (2) from right to left, for each
* row (from top to bottom); (3) from top to bottom, for each column
* (from left to right); (4) from bottom to top, for each column (from
* left to right).
*
* In each iteration, each white pixel is replaced with a transparent
* one. Each iteration ends when a pixel of color other than white (or
* a transparent pixel) is encountered.
*/
if (source == null) {
throw new IllegalArgumentException("ImageUtilities.makeBackgroundTransparent -> null source image");
}
if (source instanceof FontImage) {
source = ((FontImage) source).toImage();
}
int[] pixels = source.getRGB(); // array instance containing the ARGB data within this image
int width = source.getWidth();
int height = source.getHeight();
int tolerance = 1000000; // value chosen through several attempts
// check if the first pixel is transparent
if ((pixels[0] >> 24) == 0x00) {
return source; // nothing to do, the image already has a transparent background
}
Log.p("Converting white background to transparent...", Log.DEBUG);
// 1. Left to right, for each row (top to bottom)
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int color = pixels[y * width + x];
if ((color >> 24) != 0x00 && color >= ColorUtil.WHITE - tolerance && color <= ColorUtil.WHITE + tolerance) { // means white with tolerance and no transparency
pixels[y * width + x] = 0x00; // means full transparency
} else {
break;
}
}
}
// 2. Right to left, for each row (top to bottom)
for (int y = 0; y < height; y++) {
for (int x = width - 1; x >= 0; x--) {
int color = pixels[y * width + x];
if ((color >> 24) != 0x00 && color >= ColorUtil.WHITE - tolerance && color <= ColorUtil.WHITE + tolerance) { // means white with tolerance and no transparency
pixels[y * width + x] = 0x00; // means full transparency
} else {
break;
}
}
}
// 3. Top to bottom, for each column (from left to right)
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int color = pixels[y * width + x];
if ((color >> 24) != 0x00 && color >= ColorUtil.WHITE - tolerance && color <= ColorUtil.WHITE + tolerance) { // means white with tolerance and no transparency
pixels[y * width + x] = 0x00; // means full transparency
} else {
break;
}
}
}
// 4. Bottom to top, for each column (from left to right)
for (int x = 0; x < width; x++) {
for (int y = height - 1; y >= 0; y--) {
int color = pixels[y * width + x];
if ((color >> 24) != 0x00 && color >= ColorUtil.WHITE - tolerance && color <= ColorUtil.WHITE + tolerance) { // means white with tolerance and no transparency
pixels[y * width + x] = 0x00; // means full transparency
} else {
break;
}
}
}
return EncodedImage.createFromRGB(pixels, width, height, false);
}

