Сохранить буферизованное изображение с прозрачным фоном - программирование
Подтвердить что ты не робот

Сохранить буферизованное изображение с прозрачным фоном

Я сохраняю изображение подписи как изображение .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;
}

Я попытался установить его прозрачным, но без успеха, поэтому я разместил эту рабочую часть.

4b9b3361

Ответ 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);
    }
}