43 votes

Découper l'image en forme de texte

J'ai besoin de découper une image en forme du texte dans une autre image. Je pense que c'est mieux indiqué dans les images.

C'est une photo d'un chat:

Photo of a nice cat

et c'est le texte que je souhaite découper:

Text to cut out of the cat photo

L'image qui en résulte est celle-ci:

Resulting cut-out of the cat photo

Le texte de l'image sera toujours en noir avec un fond transparent, et de la découpe, ce qui devrait aussi avoir un fond transparent. Les deux images d'entrée sera également de la même taille.

33voto

Andrew Thompson Points 108505

Chat texte

 import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.net.URL;
import java.io.File;

class PictureText {

    public static void main(String[] args) throws Exception {
        URL url = new URL("http://i.stack.imgur.com/Nqf3H.jpg");

        final BufferedImage originalImage = ImageIO.read(url);
        int width = originalImage.getWidth();
        int height = originalImage.getHeight();
        final BufferedImage textImage = new BufferedImage(
            width,
            height,
            BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = textImage.createGraphics();

        FontRenderContext frc = g.getFontRenderContext();
        Font font = new Font("Arial", Font.BOLD, 250);
        GlyphVector gv = font.createGlyphVector(frc, "Cat");
        Rectangle2D box = gv.getVisualBounds();

        int xOff = 25+(int)-box.getX();
        int yOff = 80+(int)-box.getY();

        Shape shape = gv.getOutline(xOff,yOff);
        g.setColor(Color.WHITE);
        g.setClip(shape);
        g.drawImage(originalImage,0,0,null);

        g.setClip(null);
        g.setStroke(new BasicStroke(2f));
        g.setColor(Color.BLACK);
        g.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g.draw(shape);

        g.dispose();

        ImageIO.write(textImage,"png",new File("cat-text.png"));

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JLabel originalLabel = new JLabel(
                    new ImageIcon(originalImage));
                JLabel textLabel = new JLabel(
                    new ImageIcon(textImage));

                JPanel gui = new JPanel(new GridLayout(0,1,5,5));
                gui.add(originalLabel);
                gui.add(textLabel);

                JOptionPane.showMessageDialog(null,gui);
            }
        });
    }
}
 

21voto

Martijn Courteaux Points 33836

Créez une nouvelle BufferedImage et parcourez tous les pixels du mot cat. Si ceux-ci sont en noir, copiez les pixels de l'image du chat dans la nouvelle image.

Voici du code: ( Code de travail final, supporte l'anti-alias )

 public static BufferedImage textEffect(BufferedImage image, BufferedImage text) {
    if (image.getWidth() != text.getWidth() ||
        image.getHeight() != text.getHeight())
    {
        throw new IllegalArgumentException("Dimensions are not the same!");
    }
    BufferedImage img = new BufferedImage(image.getWidth(),
                                          image.getHeight(),
                                          BufferedImage.TYPE_INT_ARGB_PRE);

    for (int y = 0; y < image.getHeight(); ++y) {
        for (int x = 0; x < image.getWidth(); ++x) {
           int textPixel = text.getRGB(x, y);
           int textAlpha = (textPixel & 0xFF000000);
           int sourceRGB = image.getRGB(x, y);
           int newAlpha = (int) (((textAlpha >> 24) * (sourceRGB >> 24)) / 255d);
           int imgPixel = (newAlpha << 24) |  (sourceRGB & 0x00FFFFFF);
           int rgb = imgPixel | textAlpha;
           img.setRGB(x, y, rgb);

        }
    }
    return img;
}
 

15voto

StanislavL Points 31343

Utilisez GlyphVector . Utilisez Font class

 public GlyphVector layoutGlyphVector(FontRenderContext frc,
                                         char[] text,
                                         int start,
                                         int limit,
                                         int flags) {
 

Vous pouvez obtenir le contour Shape du vecteur de glyphes par forme abstraite publique Shape getOutline()

Attribuez le contour Shape tant que clip à votre instance Graphics .

Dessine l'image sur le graphique.

Seule la forme coupée sera remplie.

8voto

belisarius Points 45827

Pas de java ici, mais les opérations d’image nécessaires sont faciles à comprendre. Dans Mathematica:

entrez la description de l'image ici

2voto

Gabriel Archanjo Points 1673

Vous pouvez le faire en Java avec seulement quelques lignes de code source, en utilisant Marvin Framework

entrez la description de l'image ici

code source:

 public class CutAndFill {
    public static void main(String[] args) {
        // 1. Load images
        MarvinImage catImage = MarvinImageIO.loadImage("./res/catImage.jpg");
        MarvinImage catText = MarvinImageIO.loadImage("./res/catText.png");

        // 2. Load plug-in, set parameters and process de image
        MarvinImagePlugin combine = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.combine.combineByMask");
        combine.setAttribute("combinationImage", catImage);
        combine.setAttribute("colorMask", Color.black);
        combine.process(catText.clone(), catText);

        // 3. Save the output image.
        MarvinImageIO.saveImage(catText, "./res/catOut.jpg");
    }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X