Reputation: 117
I already have a working API in java that takes text in request, and creates a PNG image from this text using custom fonts and returns a BASE64 encoded data of the image.
Now, I need to modify this method to support two row to be displayed in scrolling on a physical hardware device.
Requirement : if the text input in request contains pipe ('|') it's a two row content.
Existing code for single row image (this works fine) :
String text = request.getTextValue();
ClassPathResource resource = new ClassPathResource("/font/pg-led-16pt.ttf");
InputStream inputStream = resource.getInputStream();
Font font = Font.createFont(Font.PLAIN, inputStream).deriveFont(Font.PLAIN, 14f);
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setFont(font);
FontMetrics fm = g2d.getFontMetrics();
int width = fm.stringWidth(text);
int height = fm.getHeight();
g2d.dispose();
Color customTextColor = new Color(request.getDisplayColor().getR(), request.getDisplayColor().getG(), request.getDisplayColor().getB());
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g2d.setFont(font);
fm = g2d.getFontMetrics();
g2d.setColor(customTextColor);
g2d.drawString(text, 0, fm.getAscent());
g2d.dispose();
BufferedImage newImage;
if (img.getWidth() < 60) {
newImage = ImageUtilities.addBlackBackground(img, request.getBackgroundColor(), request.getAlignment() == null ? null : request.getAlignment());
} else {
newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = newImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g2d.setColor(request.getBackgroundColor() == null ? Color.BLACK : new Color(
request.getBackgroundColor().getR(),
request.getBackgroundColor().getG(),
request.getBackgroundColor().getB()
));
g2d.fillRect(0, 0, width, height);
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmm");
String fileName = name == null ? ZonedDateTime.now().format(formatter) : name;
File file = new File(fileName.concat(".png"));
try {
BufferedImage resizedImage = ImageUtilities.resizeImage(newImage, newImage.getWidth(),
request.getHeight() == null || request.getHeight() == 0 ? 16 : request.getHeight(),
request.getScaling(), Image.SCALE_DEFAULT);
ImageIO.write(resizedImage, "png", file);
String imageName = file.getName();
String url = null;
byte[] response = FileUtils.readFileToByteArray(file);
File ppmFile = null ;
if (request.getImageType()!=null && request.getImageType().equals(ImageFormat.PPM)){
ppmFile = ImageUtilities.convertPngToPPM(file,imageName, null, true);
response = FileUtils.readFileToByteArray(ppmFile);
}
if (request.getCreateFile()!= null && request.getCreateFile()){
String key = folderKey == null ? "s3/customers/"+request.getCustomerId()+"/textpreviews/" : folderKey;
if (request.getImageType()==null || request.getImageType().toString().isEmpty() || request.getImageType().equals(ImageFormat.PNG)){
url = s3Factory.uploadFile(file, key);
}
if (request.getImageType()!=null && request.getImageType().equals(ImageFormat.PPM)){
url = s3Factory.uploadFile(ppmFile, key);
}
}
TextToImageResponse finalResponse = new TextToImageResponse();
finalResponse.setCode(response);
finalResponse.setHeight(resizedImage.getHeight());
finalResponse.setWidth(resizedImage.getWidth());
finalResponse.setS3Url(url);
file.delete();
return AppResponse.responseOk("Success", finalResponse);
} catch (IOException ex) {
ex.printStackTrace();
return AppResponse.responseError(400, "Something went wrong while processing the Image");
}
public static BufferedImage addBlackBackground(BufferedImage img, DisplayColor backgroundColor, Alignment alignment) {
// Default values for background color and alignment
Color background = (backgroundColor != null) ?
new Color(backgroundColor.getR(), backgroundColor.getG(), backgroundColor.getB()) :
Color.BLACK;
// Calculate X and Y offsets based on the alignment
int x = 0;
int y;
int imageWidth = img.getWidth();
int imageHeight = img.getHeight();
if (alignment == null) {
x = (60 - img.getWidth()) / 2;
y = (16 - img.getHeight()) / 2;
} else {
y = switch (alignment) {
case left -> (16 - imageHeight) / 2;
case center -> {
x = (60 - imageWidth) / 2;
yield (16 - imageHeight) / 2;
}
case right -> {
x = 60 - imageWidth;
yield (16 - imageHeight) / 2;
}
};
}
BufferedImage newImage = new BufferedImage(60, 16, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = newImage.createGraphics();
g2d.setColor(background);
g2d.fillRect(0, 0, 60, 16);
g2d.drawImage(img, x, y, null);
g2d.dispose();
return newImage;
}
public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight, Integer scale, int scalingProperty) {
if (scale != null && scale > 1) {
targetHeight = targetHeight * scale;
targetWidth = targetWidth * scale;
}
Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, scalingProperty);
BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
return outputImage;
}
**Two Row image code (doesn't work) : **
String text = request.getTextValue();
// Check for two-row text logic
String[] textRows = text.split("\\|", 2);
String topRow = textRows[0].trim();
String bottomRow = textRows.length > 1 ? textRows[1].trim() : null;
// Use special font for two-row text if applicable
Font font;
if (bottomRow != null) {
ClassPathResource specialFontResource = new ClassPathResource("/font/pg-led-9-pt.ttf");
InputStream specialFontInputStream = specialFontResource.getInputStream();
font = Font.createFont(Font.PLAIN, specialFontInputStream).deriveFont(Font.PLAIN, 14f);
} else {
ClassPathResource defaultFontResource = new ClassPathResource("/font/pg-led-16pt.ttf");
InputStream defaultFontInputStream = defaultFontResource.getInputStream();
font = Font.createFont(Font.PLAIN, defaultFontInputStream).deriveFont(Font.PLAIN, 14f);
}
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setFont(font);
FontMetrics fm = g2d.getFontMetrics();
int topRowWidth = fm.stringWidth(topRow);
int height = fm.getHeight();
g2d.dispose();
Color customTextColor = new Color(request.getDisplayColor().getR(), request.getDisplayColor().getG(), request.getDisplayColor().getB());
// Create image for top row
BufferedImage imgTopRow = new BufferedImage(topRowWidth, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2dTopRow = imgTopRow.createGraphics();
g2dTopRow.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g2dTopRow.setFont(font);
fm = g2dTopRow.getFontMetrics();
g2dTopRow.setColor(customTextColor);
g2dTopRow.drawString(topRow, 0, fm.getAscent());
g2dTopRow.dispose();
// Create image for bottom row if applicable
BufferedImage imgBottomRow = null;
if (bottomRow != null) {
int bottomRowWidth = fm.stringWidth(bottomRow);
imgBottomRow = new BufferedImage(bottomRowWidth, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2dBottomRow = imgBottomRow.createGraphics();
g2dBottomRow.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g2dBottomRow.setFont(font);
fm = g2dBottomRow.getFontMetrics();
g2dBottomRow.setColor(customTextColor);
g2dBottomRow.drawString(bottomRow, 0, fm.getAscent());
g2dBottomRow.dispose();
}
// Combine images if there is a bottom row
BufferedImage newImage;
if (imgBottomRow != null) {
newImage = ImageUtilities.combineImages(imgTopRow, imgBottomRow);
} else {
newImage = imgTopRow;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmm");
String fileName = name == null ? ZonedDateTime.now().format(formatter) : name;
File file = new File(fileName.concat(".png"));
try {
BufferedImage resizedImage = ImageUtilities.resizeImage(newImage, newImage.getWidth(),
request.getHeight() == null || request.getHeight() == 0 ? 16 : request.getHeight(),
request.getScaling(), Image.SCALE_DEFAULT);
ImageIO.write(resizedImage, "png", file);
String imageName = file.getName();
String url = null;
byte[] response = FileUtils.readFileToByteArray(file);
File ppmFile = null ;
if (request.getImageType()!=null && request.getImageType().equals(ImageFormat.PPM)){
ppmFile = ImageUtilities.convertPngToPPM(file,imageName, null, true);
response = FileUtils.readFileToByteArray(ppmFile);
}
if (request.getCreateFile()!= null && request.getCreateFile()){
String key = folderKey == null ? "s3/customers/"+request.getCustomerId()+"/textpreviews/" : folderKey;
if (request.getImageType()==null || request.getImageType().toString().isEmpty() || request.getImageType().equals(ImageFormat.PNG)){
url = s3Factory.uploadFile(file, key);
}
if (request.getImageType()!=null && request.getImageType().equals(ImageFormat.PPM)){
url = s3Factory.uploadFile(ppmFile, key);
}
}
TextToImageResponse finalResponse = new TextToImageResponse();
finalResponse.setCode(response);
finalResponse.setHeight(resizedImage.getHeight());
finalResponse.setWidth(resizedImage.getWidth());
finalResponse.setS3Url(url);
file.delete();
return AppResponse.responseOk("Success", finalResponse);
} catch (IOException ex) {
ex.printStackTrace();
return AppResponse.responseError(400, "Something went wrong while processing the Image");
}
}
public static BufferedImage combineImages(BufferedImage topImage, BufferedImage bottomImage) {
int combinedWidth = Math.max(topImage.getWidth(), bottomImage.getWidth());
int combinedHeight = 16; // Set height to a fixed value (16 in this case)
BufferedImage combinedImage = new BufferedImage(combinedWidth, combinedHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = combinedImage.createGraphics();
g2d.drawImage(topImage, 0, 0, null);
g2d.drawImage(bottomImage, 0, 8, null);
g2d.dispose();
return combinedImage;
}
Image generated using the two Row code :
Upvotes: 1
Views: 23