前言
在开发中,点阵图有时候需要更改北京图片,比如白底黑字,或者黑底白字,这个时候,只需要把点阵图所有字节取反,就可以更改背景颜色
更改背景颜色
以行列式为标准,然后生成的字节取反
ini
package cn.com.ut.oct.pic;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
public class EInkDisplaySDK {
// 支持的字体样式
public enum FontStyle {
PLAIN, BOLD, ITALIC
}
/**
* 将文本转换为点阵数据
*
* @param text 要转换的文本
* @param fontSize 字体大小
* @param fontStyle 字体样式
* @param width 显示区域宽度
* @param height 显示区域高度
* @return 点阵数据字节数组
*/
public static byte[][] textToDotMatrix(String text, int fontSize, FontStyle fontStyle,
int width, int height) {
// 创建字体
Font font = new Font("宋体", getAwtFontStyle(fontStyle), fontSize);
// 创建临时图像进行渲染
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g2d = image.createGraphics();
// 设置渲染参数
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.BLACK);
g2d.setFont(font);
// 计算文本位置(居中)
String[] data = text.split(",");
int margin = 10;
int high = 30;
int count = 0;
double angleInRadians = Math.toRadians(90);
// g2d.rotate(angleInRadians, image.getWidth() / 2, image.getHeight() / 2);
for (String str : data) {
count++;
// 绘制文本
// g2d.scale(-1.0, 1.0);
FontMetrics metrics = g2d.getFontMetrics();
int x = (width - metrics.stringWidth(str)) / 2;
int y = ((height - metrics.getHeight()) / 2) + metrics.getAscent();
g2d.drawString(str, x, high);
if (count > 0) {
high = high + 30;
}
}
g2d.dispose();
// 创建一个新的BufferedImage对象,用于存储旋转后的图片
BufferedImage destImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
// 获取Graphics2D对象
Graphics2D graphics2D = (Graphics2D) destImage.getGraphics();
// 创建一个新的AffineTransform对象,并设置其为旋转变换
AffineTransform transform = new AffineTransform();
transform.rotate(Math.toRadians(90), image.getWidth() / 2, image.getHeight() / 2);
// 使用Graphics2D对象的drawImage方法,将原始图片按照旋转变换绘制到新的BufferedImage对象上
graphics2D.drawImage(image, transform, null);
// 转换图像为点阵数据
return convertImageToDotMatrix1(destImage, width, height);
}
/**
* 将图像转换为点阵数据
*/
private static byte[][] convertImageToDotMatrix(BufferedImage image, int width, int height) {
// 计算每列需要的字节数(每8个像素用1字节表示)
int bytesPerColumn = (int) Math.ceil(height / 8.0);
int totalBytes = bytesPerColumn * width;
try {
ImageIO.write(image, "jpeg", new File("d:/hello/1.jpeg"));
} catch (IOException e) {
throw new RuntimeException(e);
}
// BufferedImage image1 = getImage("d:/hello/1.jpeg");
//
// try {
// ImageIO.write(image1, "jpeg", new File("d:/hello/2.jpeg"));
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
byte[][] dotMatrix = new byte[bytesPerColumn][width];
ByteBuffer buffer = ByteBuffer.allocate(totalBytes);
for (int x = 0; x < width; x++) {
for (int byteIdx = 0; byteIdx < bytesPerColumn; byteIdx++) {
byte b = 0;
for (int bit = 0; bit < 8; bit++) {
int pixelY = byteIdx * 8 + bit;
if (pixelY < height) {
int rgb = image.getRGB(x, pixelY);
// 如果像素不是白色(即黑色文本),设置对应位
if (rgb != Color.WHITE.getRGB()) {
b |= (1 << bit); // 列主序时位顺序与行主序不同
}
}
}
// buffer.put(b);
dotMatrix[byteIdx][x] = b;
}
}
return dotMatrix;
}
/**
* 将图像转换为点阵数据
*/
private static byte[][] convertImageToDotMatrix1(BufferedImage image, int width, int height) {
int bytesPerRow = (int) Math.ceil(width / 8.0);
; // 每行需要的字节数
// byte[] dotMatrix = new byte[bytesPerRow * height];
byte[][] dotMatrix = new byte[bytesPerRow][height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < bytesPerRow; x++) {
byte b = 0;
for (int bit = 0; bit < 8; bit++) {
int pixelX = x * 8 + bit;
if (pixelX < width) {
int rgb = image.getRGB(pixelX, y);
// 黑色像素设置对应位
if (rgb != Color.WHITE.getRGB()) {
int actualBit = 7 - bit;
b |= (1 << actualBit);
}
}
}
b = (byte) ~b;
dotMatrix[x][y] = b;
}
}
// 输出图像到文件
File outputFile = new File("d:/hello/output.png");
try {
ImageIO.write(image, "png", outputFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
return dotMatrix;
}
public static BufferedImage getImage(String srcFile) {
// 读取原始图片
BufferedImage srcImage = null;
try {
srcImage = ImageIO.read(new File(srcFile));
} catch (IOException e) {
throw new RuntimeException(e);
}
// 创建一个新的BufferedImage对象,用于存储旋转后的图片
BufferedImage destImage = new BufferedImage(srcImage.getWidth(), srcImage.getHeight(), srcImage.getType());
// 获取Graphics2D对象
Graphics2D graphics2D = (Graphics2D) destImage.getGraphics();
// 创建一个新的AffineTransform对象,并设置其为旋转变换
AffineTransform transform = new AffineTransform();
transform.rotate(Math.toRadians(90), srcImage.getWidth() / 2, srcImage.getHeight() / 2);
// 使用Graphics2D对象的drawImage方法,将原始图片按照旋转变换绘制到新的BufferedImage对象上
graphics2D.drawImage(srcImage, transform, null);
// // 将旋转后的图片保存到文件
//
//
// ImageIO.write(destImage, "JPG", new File("d:/hello/dest.jpg"));
return destImage;
}
/**
* 字体样式转换
*/
private static int getAwtFontStyle(FontStyle style) {
switch (style) {
case BOLD:
return Font.BOLD;
case ITALIC:
return Font.ITALIC;
default:
return Font.PLAIN;
}
}
/**
* 多行文本转换(支持自动换行)
*/
public static List<byte[][]> multiLineTextToDotMatrix(String text, int fontSize,
FontStyle fontStyle,
int width, int height,
int lineHeight) {
List<String> lines = wrapText(text, width, fontSize, fontStyle);
List<byte[][]> result = new ArrayList<>();
for (String line : lines) {
result.add(textToDotMatrix(line, fontSize, fontStyle, width, lineHeight));
}
return result;
}
/**
* 文本自动换行处理
*/
private static List<String> wrapText(String text, int maxWidth, int fontSize, FontStyle fontStyle) {
// 简化的换行实现,实际应用中需要更复杂的逻辑
List<String> lines = new ArrayList<>();
Font font = new Font("SimSun", getAwtFontStyle(fontStyle), fontSize);
// 这里应该使用FontMetrics计算文本宽度并进行换行
// 简化实现:按字符数粗略分割
int charsPerLine = maxWidth / fontSize * 2; // 粗略估算
for (int i = 0; i < text.length(); i += charsPerLine) {
int end = Math.min(i + charsPerLine, text.length());
lines.add(text.substring(i, end));
}
return lines;
}
/**
* 生成用于墨水屏刷新的压缩数据
*/
public static byte[] generateCompressedData(byte[] dotMatrix, int width, int height) {
// 简化的压缩实现,实际应根据墨水屏协议实现
List<Byte> compressed = new ArrayList<>();
byte currentByte = dotMatrix[0];
int count = 1;
for (int i = 1; i < dotMatrix.length; i++) {
if (dotMatrix[i] == currentByte && count < 255) {
count++;
} else {
compressed.add((byte) count);
compressed.add(currentByte);
currentByte = dotMatrix[i];
count = 1;
}
}
compressed.add((byte) count);
compressed.add(currentByte);
// 转换为字节数组
byte[] result = new byte[compressed.size()];
for (int i = 0; i < compressed.size(); i++) {
result[i] = compressed.get(i);
}
return result;
}
}
测试用例
ini
public class EInkExample {
static void main(String[] args) throws IOException {
String str = "优秀";
byte[][] dotMatrix = EInkDisplaySDK.textToDotMatrix(
str,
24,
EInkDisplaySDK.FontStyle.PLAIN,
152,
152
);
List<Integer> list = new ArrayList<>(10);
for (int i = 0; i < dotMatrix.length; i++) {
for (int j = 0; j < dotMatrix[i].length; j++) {
list.add((int) dotMatrix[i][j]);
System.out.print(HexUtil.toHex((dotMatrix[i][j] & 0XFF)) + ",");
}
System.out.println();
}
// byte[] a = new byte[list.size()];
// for (int i = 0; i < list.size(); i++) {
// a[i] = list.get(i).byteValue();
// System.out.print(a[i] + " ");
// if ((i + 1) % 128 == 0) {
// System.out.println();
// }
//
// }
//
// System.out.println();
// System.out.println("=================");
//
// System.out.println();
}
}
总结
可以使用点阵图去更改显示屏文字颜色