Сохранить буферизованное изображение с прозрачным фоном
Я сохраняю изображение подписи как изображение .jpg. Я использую graphic2d, чтобы нарисовать на изображении каждый пиксель подписи (полученный с подписным планшетом), и он отлично работает, но я всегда получаю белый фон.
Если я хочу поставить подпись в PDF-документе, границы белого квадрата jpg-изображения охватывают некоторые слова PDF.
Что я хочу получить, так это сохранить изображение в формате jpg с прозрачным фоном, поэтому, когда я помещаю его в PDF, нет слов, покрытых белым фоном изображения, а только линий подписи.
Это код, который сохраняет буферное изображение. Он делает это на белом фоне.
// This method refers to the signature image to save
private RenderedImage getImage() {
int width = tabletWidth;
int height = tabletHeight;
// Create a buffered image in which to draw
BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// Create a graphics contents on the buffered image
Graphics2D g2d = bufferedImage.createGraphics();
// Draw graphics
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
drawPoints(Tablet.getPenPoints(), g2d, Color.BLACK);
// Graphics context no longer needed so dispose it
g2d.dispose();
return bufferedImage;
}
Я попытался установить его прозрачным, но без успеха, поэтому я разместил эту рабочую часть.
Ответы
Ответ 1
Используйте BufferedImage.TYPE_INT_ARGB
вместо BufferedImage.TYPE_INT_RGB
. И сохраните его на PNG
изображении, JPEG
не поддерживает прозрачность.
UPD:
Для установки прозрачного фона используйте его:
g2d.setComposite(AlphaComposite.Clear);
g2d.fillRect(0, 0, w, h);
И для рисования вашего изображения:
g2d.setComposite(AlphaComposite.Src);
drawPoints(Tablet.getPenPoints(), g2d, Color.BLACK);
Ответ 2
Как уже упоминалось, вы не можете сохранять JPEG с прозрачностью.
Однако, возможно сохранить ваш файл так же, как и вы (в формате JPEG, хотя я предлагаю использовать в этом случае полутоновый JPEG), а затем интерпретировать белые части как прозрачные, а черные - как непрозрачные (т.е. использовать изображение в оттенках серого как альфа-маска). Затем вы можете просто раскрасить непрозрачные части, черные или синие, чтобы выглядеть как ручка.
Подумайте о белой области, как о бумаге, и о черных частях, покрытых чернилами. Обратите внимание, что этот метод будет работать только в случае использования, когда все белые пиксели должны быть прозрачными. Другие ответы в этом потоке будут работать лучше в общем случае.
Ответ 3
JPEG не поддерживает трансперенситивность. Вы должны использовать другой целевой формат, например png.
Ответ 4
У вас настроено буферизованное изображение типа RGB, не имеющего альфа-компонента, вам нужно будет использовать тот, у которого есть альфа, чтобы поддерживать прозрачность.
Ответ 5
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
// ready to use end to end example
// it will create png picture with transparency and 2 x rectangles
// compilation time - 2019_04_10__00_12_03_236
public class java_create_png_image_with_transparency_end_to_end_example {
public static void main(String[] args) throws IOException {
Path outPath = Paths.get("C:\\_tmp_out_\\");
if (!Files.exists(outPath)) {
Files.createDirectory(outPath);
}
String timeNow = DateTimeFormatter
.ofPattern("yyyy_MM_dd__HH_mm_ss_SSS")
.format(LocalDateTime.now());
String filename = "test_png_pic__" + timeNow + "__.png";
File absOutFile = outPath.resolve(filename).toFile();
int width = 300;
int height = 300;
BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.setComposite(AlphaComposite.Clear);
g2d.fillRect(0, 0, width, height);
g2d.setComposite(AlphaComposite.Src);
int alpha = 127; // 50% transparent
g2d.setColor(new Color(255, 100, 100, alpha));
g2d.fillRect(100, 100, 123, 123);
g2d.setColor(new Color(0, 0, 0));
g2d.fillRect(30, 30, 60, 60);
g2d.dispose();
ImageIO.write(bufferedImage, "png", absOutFile);
System.out.println("File saved to:");
System.out.println(absOutFile);
}
}