问题描述
我目前有一种方法可以根据模板、两个单独的头像和一个文本生成图像,然后将其作为字节数组返回。
根据所提供的 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,320,null);
img.drawImage(avatar2,640,null);
img.drawImage(template,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;
}
}
解决方法
找到了解决方案。
第二个示例似乎是可以使用的示例,我设法让此设置为我工作:
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,320,null);
img.drawImage(avatar2,640,null);
img.drawImage(template,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;
}
}