【问题标题】:How to add an outline to a text and then add it to the image's center?如何为文本添加轮廓,然后将其添加到图像的中心?
【发布时间】:2021-02-06 00:21:15
【问题描述】:

我目前有一种方法可以根据模板、两个单独的头像和一个文本生成图像,然后将其作为字节数组返回。
根据所提供的chance 整数的大小,显示的文本具有不同的颜色。

由于字体可以具有模板图像所具有的颜色,是否有可能(没有双关语)文本在结果图像上不可见,这就是为什么我想将黑色轮廓应用于显示的字体。

我已经找到this answer here,虽然它实际上给出了两个例子,但它是否让我感到困惑而不是真正帮助我。

first example 有很多我自己不需要的步骤,我不确定哪些可以丢弃,哪些必须保留。
我也不确定如何在此处将文本居中应用我的逻辑,因为该示例似乎应用了字体的轮廓并单独填充每个字母,在我的情况下这将非常烦人,并且也不能保证每个字母都相同时间,因为文本可能是#%##%###%

second example 似乎更多地是关于在 JPanel 中的使用?或者换句话说,我不确定此代码是否也可以单独应用于图像,或者是否需要修补才能仅处理图像。

我基本上需要知道使用fontColor创建字体需要哪些方法,为其添加黑色轮廓,然后将其放置在图像本身的中心,然后将其作为字节数组返回。

这是我目前用于上下文的代码。

    private final OkHttpClient CLIENT = new OkHttpClient();

    private BufferedImage getAvatar(String url) throws IOException{
        URL url = new URL(url);
        URLConnection connection = url.openConnection();
        connection.setRequestProperty("User-Agent", "ImageRenderer");
        connection.connect();

        return ImageIO.read(connection.getInputStream());
    }

    public byte[] getChance(String url1, String url2, int chance){
        try{
            BufferedImage template = ImageIO.read(new File("img/chance.png"));
            BufferedImage avatar1 = getAvatar(url1);
            BufferedImage avatar2 = getAvatar(url2);

            // Create new BufferedImage with the template's sizes.
            BufferedImage background = new BufferedImage(template.getWidth(), template.getHeight(), template.getType());

            Graphics2D img = background.createGraphics();

            Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 80);
            img.setFont(font);

            Color fontColor;

            if(chance <= 100 && chance > 74){
                fontColor = Color.GREEN;
            }else
            if(chance <= 74 && chance > 49){
                fontColor = Color.ORANGE;
            }else
            if(chance <= 49 && chance > 24){
                fontColor = Color.RED;
            }else{
                fontColor = Color.BLACK;
            }
    
            String text = chance + "%";
            
            img.setColor(fontColor);

            // Set the avatars followed by the template.
            img.drawImage(avatar1, 0, 0, 320, 320, null);
            img.drawImage(avatar2, 640, 0, 320, 320, null);
            img.drawImage(template, 0, 0, null);

            // Get the image's width and height
            int imgWidth = template.getWidth();
            int imgHeight = template.getHeight();

            // Set X and Y position for the text to be centered.
            int textX = (imgWidth / 2) - (img.getFontMetrics().stringWidth(text) / 2);
            int textY = (imgHeight / 2) - 40;

            // Draw the actual String
            img.drawString(text, textX, textY);

            img.dispose();

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.setUseCache(false);
            ImageIO.write(background, "png", baos);

            return baos.toByteArray();
        }catch(IOException ex){
            return null;
        }
    }

【问题讨论】:

    标签: java bufferedimage graphics2d


    【解决方案1】:

    找到了解决办法。

    第二个例子似乎是可以使用的,我设法让这个设置为我工作:

        private final OkHttpClient CLIENT = new OkHttpClient();
    
        private BufferedImage getAvatar(String url) throws IOException{
            URL url = new URL(url);
            URLConnection connection = url.openConnection();
            connection.setRequestProperty("User-Agent", "ImageRenderer");
            connection.connect();
    
            return ImageIO.read(connection.getInputStream());
        }
    
        public byte[] getChance(String url1, String url2, int chance){
            try{
                BufferedImage template = ImageIO.read(new File("img/chance.png"));
                BufferedImage avatar1 = getAvatar(url1);
                BufferedImage avatar2 = getAvatar(url2);
    
                // Create new BufferedImage with the template's sizes.
                BufferedImage background = new BufferedImage(template.getWidth(), template.getHeight(), template.getType());
    
                Graphics2D img = background.createGraphics();
    
                Color outlineColor = Color.BLACK;
                Color fontColor;
    
                if(chance <= 100 && chance > 74){
                    fontColor = Color.GREEN;
                }else
                if(chance <= 74 && chance > 49){
                    fontColor = Color.ORANGE;
                }else
                if(chance <= 49 && chance > 24){
                    fontColor = Color.RED;
                }else{
                    fontColor = Color.BLACK;
                }
    
                // Set the avatars followed by the template.
                img.drawImage(avatar1, 0, 0, 320, 320, null);
                img.drawImage(avatar2, 640, 0, 320, 320, null);
                img.drawImage(template, 0, 0, null);
    
                Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 80);
                
                img.setColor(fontColor);
                img.setFont(font);
    
                String text = chance + "%";
                
                img.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                img.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    
                FontRenderContext context = img.getFontRenderContext();
    
                // Set X and Y position for the text to be centred.
                int textX = (imgWidth / 2) - (img.getFontMetrics(font).stringWidth(text) / 2);
                int textY = (imgHeight / 2) + 40;
    
                // Draw the actual String
                img.drawString(text, textX, textY);
    
                // Get TextLayout and AffineTransform
                TextLayout layout = new TextLayout(text, font, context);
                AffineTransform transform = img.getTransform();
                
                // Create the Shape of the outline
                Shape outline = layout.getOutline(null);
                
                // Move position
                transform.translate(textX, textY);
                
                // Apply the shape
                img.transform(transform);
                img.setColor(outlineColor);
                img.draw(outline);
                
                img.setClip(outline);
    
                img.dispose();
    
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ImageIO.setUseCache(false);
                ImageIO.write(background, "png", baos);
    
                return baos.toByteArray();
            }catch(IOException ex){
                return null;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2022-07-26
      • 1970-01-01
      • 2021-09-09
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 1970-01-01
      相关资源
      最近更新 更多