您的位置:首页 > 电脑网络 > 笔记本 > 如何在没有安装汉字字体的linux机器上绘制包含汉字的图片?

如何在没有安装汉字字体的linux机器上绘制包含汉字的图片?

luyued 发布于 2011-02-03 21:22   浏览 N 次  

前一段时间为了绘制随机的幽默笑话作为背景图片显示在我的空间上,在本机测试无误后上传到一个国外的开发服务器,无奈所有的汉字都显示不了.取得所有安装的字体来测试绘制汉字也都是乱码,看来老外就没有考虑过给我安装过一个中文字体!也没有办法联系上老外要他给我装个字体,只好自己想办法了.

在sf上搜索到了一个bitmapfontcreator 项目,是用来输出一个字符串保存为bmp位图文件.觉得这个可能用的上.我只要解析bmp文件的格式然后找出对应的绘制字符的点,保存成字模文件,然后在绘制汉字的时候根据次字模文件不就可以绘制汉字了吗?就按照这个思路做,终于绘制出来了,心里很是高兴呢.

下面就发表一些代码片断,予以纪念吧:

//按照指定的中文字体,背景色,字体颜色绘制一个字符到BufferedImage
public BufferedImage renderBitmapFont(Font font, Color bgColor, Color frontColor, char ch) {
String theCharacters=String.valueOf(ch);
calculateBitmapSize(font, theCharacters);
if(picWidth<=0||picHeight<=0){
return null;
}
BufferedImage fontImg = defaultConfiguration.createCompatibleImage(picWidth, picHeight, 2);
Graphics2D gfx = (Graphics2D) fontImg.getGraphics();
gfx.setFont(font);
gfx.setColor(bgColor);

gfx.fillRect(0, 0, picWidth, picHeight);

BufferedImage bufferedImage = renderBitmapFontSpecific(gfx, fontImg, frontColor, theCharacters);
gfx.dispose();

BufferedImage fontImg2 = defaultConfiguration.createCompatibleImage(picWidth, picHeight, 1);
Graphics2D gfx2 = (Graphics2D) fontImg2.getGraphics();
gfx2.drawImage(bufferedImage, 0, 0, null);
gfx2.dispose();
return fontImg2;
}

//将生成的字符图片按照bmp格式保存到数组中,以备解析bmp数据
private void toDataArray(BufferedImage img) throws IOException {
String ext = "bmp";
ByteArrayOutputStream bout = new ByteArrayOutputStream(1024);
BufferedOutputStream bbout=new BufferedOutputStream(bout);
TLong.getTLong("ImageIO.write").begin();
ImageIO.write(img, ext, bout); //此操作占据了90%的执行时间,sun的类库效率有待提高啊
TLong.getTLong("ImageIO.write").end();
bbout.flush();
bout.flush();

byte[] bytes=bout.toByteArray();
data = new int[bytes.length];
for (int i = 0, len = data.length; data != null &&i byte aByte = bytes[i];
if (aByte <0) {
data[i] = 256 + aByte;
} else {
data[i] = aByte;
}
}
}

//解析字符生成的位图信息,用1bit保存字符点阵对应位置该画还是不画
private void toMatrix() throws IOException {

long datastartoffset = asLong(read(0x000A, 4)); //参照bmp文件格式的定义
int W = (int) asLong(read(0x0012, 4));
int H = (int) asLong(read(0x0016, 4));
CharMask bit = new CharMask(W,achar);
int total = W * H;
for (int i = 0; i long value = asLong(read((int) (i * 2 + datastartoffset), 2));
int red = (int) (value &0x7C00) >>10;
int green = (int) (value &0x03E0) >>5;
int blue = (int) (value &0x001F);
if (red != 31 || green != 31 || blue != 31) {
bit.set(i);
}
// System.err.println("red:"+red+ "green:"+green+" blue:"+blue);
}

bit.writeTo(this.out);
}

//在给定坐标根据字模信息绘制汉字,返回字符占据的宽度(按像素)
public static int drawChar(Graphics2D g, char ch, int x, int y) {
char[] cdata = gb.load(ch);
if (cdata == null) {
System.err.println("no cdata for char:[" + ch + "],hex:" + Integer.toHexString(ch));
return 0;
}

int chwpx = cdata[0];
int dy = 0;
StackPrint sp = new StackPrint();
for (int i = 1; i char chbit = cdata[i];
for (int bit = 0; bit <16; bit++) {
if (((i - 1) * 16 + bit) % chwpx == 0) {
sp.endLine();
}
if ((chbit &(1 <0) {
sp.print("#");

if (g != null) {
int bitLength = (i - 1) * 16 + bit;
int yp = y + (12-bitLength / chwpx);
int xp = x + bitLength%chwpx;
g.drawLine(xp, yp, xp, yp);
}
} else {
sp.print(" ");
}
}
}
String content = sp.getContent();
// System.err.println(content);
return chwpx;
}

广告赞助商