Водяной знак на изображении TIFF - PullRequest
1 голос
/ 20 июня 2019

Я пытаюсь нанести водяной знак на изображения, используя Java.В настоящее время я ставлю водяные знаки на изображения с расширением с помощью png, jpeg, но код не работает на TIFF изображении.Раньше он выдавал ошибку нулевого указателя, но после включения двенадцати файловых ключей ядра и tiff ошибка нулевого указателя пропала, и код выполняется построчно.Но у выходного изображения tiff нет водяного знака.

            BufferedImage sourceImage = ImageIO.read(...);
            Graphics2D g2d = (Graphics2D) sourceImage.getGraphics();

            AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f);
            g2d.setComposite(alphaChannel);
            g2d.setColor(Color.BLACK);
            g2d.setFont(new java.awt.Font("Times New Roman", Font.BOLD, 64));
            FontMetrics fontMetrics = g2d.getFontMetrics();
            Rectangle2D rect = fontMetrics.getStringBounds(watermarkText, g2d);

            int centerX = (sourceImage.getWidth() - (int) rect.getWidth()) / 2;
            int centerY = sourceImage.getHeight() / 2;

            FontMetrics fm = g2d.getFontMetrics();

            g2d.drawString(watermarkText, centerX, centerY);

            ImageIO.write(sourceImage,extension, outFile);

Может кто-нибудь дать способ нанести водяной знак на изображение tiff?

1 Ответ

3 голосов
/ 21 июня 2019

Как уже указывалось в комментариях к вопросу, проблема, скорее всего, не в том, что ваш код "неправильный" или что-то специфическое для формата TIFF предотвращает использование водяных знаков.

Однако TIFF - это очень гибкий формат, который может содержать что угодно: от RGB, CMYK, «глубоких цветов» или плавающих образцов до простых индексированных или двухуровневых данных изображения.Я подозреваю, что проблема связана с последним (и если да, то у вас будет такая же проблема с некоторыми PNG палитры), так как в этих случаях могут отсутствовать цвета, которые могут представлять ваш прозрачный черный цвет.Но невозможно сказать наверняка, без дальнейших разъяснений.

Такие проблемы легко исправить, создав полное изображение RGB в памяти, нарисовав на нем оригинал и добавив водяной знак.Но это резко изменило бы выходной файл и размер, и я не знаю, приемлемо ли это для вашего случая использования.


В любом случае, вот полный рабочий пример, основанный на вашем коде выше и с проверяемыми файлами ввода / вывода:

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class WatermarkTest {

    private static String watermarkText = "WaterMark!";

    public static void main(String[] args) throws IOException {
        File input = new File(args[0]);
        String extension = getExtension(input);

        File output = args.length >= 2 
                ? new File(args[1]) 
                : new File(input.getParent(), input.getName().replace("." + extension, "_watermarked." + extension));

        BufferedImage sourceImage = ImageIO.read(input);
        Graphics2D g2d = sourceImage.createGraphics();

        AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f);
        g2d.setComposite(alphaChannel);
        g2d.setColor(Color.BLACK);
        g2d.setFont(new java.awt.Font("Times New Roman", Font.BOLD, 64));
        FontMetrics fontMetrics = g2d.getFontMetrics();
        Rectangle2D rect = fontMetrics.getStringBounds(watermarkText, g2d);

        int centerX = (sourceImage.getWidth() - (int) rect.getWidth()) / 2;
        int centerY = sourceImage.getHeight() / 2;

        g2d.drawString(watermarkText, centerX, centerY);

        g2d.dispose();

        ImageIO.write(sourceImage, extension, output);
    }

    private static String getExtension(final String fileName) {
        int index = fileName.lastIndexOf('.');

        if (index >= 0) {
            return fileName.substring(index + 1);
        }

        // No period found
        return null;
    }
}

Входное изображение: logo.tif

logo.tif

Изображение результата: logo_watermarked.tif

logo_watermarked.tif

К сожалению, загрузка в Stackoverflow преобразовалаизображения в PNG.Исходные файлы ввода и вывода в формате TIFF можно загрузить с Dropbopx .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...