如何在没有安装汉字字体的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
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
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
for (int bit = 0; bit <16; bit++) {
if (((i - 1) * 16 + bit) % chwpx == 0) {
sp.endLine();
}
if ((chbit &(1 <
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;
}
- 06-02· 【转】 给Ubuntu安装netboo
- 06-02· Netbook
- 05-31· 你搜“联宝戏” 揭示你未
- 05-31· 联宝戏一切成功都是那么
- 05-31· 联宝(LINPO)
- 05-31· 台湾联宝CY25 ¥1400
- 05-31· 透视!笔记本奸商的无间道
- 05-31· 沈阳惠普笔记本维修千万
- 05-31· 重庆联宝活性炭恭祝各位
- 05-31· [转载]第十步:移联宝移动
- 05-28· 高端便携商务本 富士通
- 05-27· 富士通推首台器MeeGo新本
- 05-27· 富士通云计算方案三级跳
- 05-26· 惠普 Compaq 6530B(VA078PA)
- 05-26· of Alienware M14xAkku HP Compaq
- 05-26· ASUS HP COMPAQ DELL 笔记...
- 05-26· 惠普Compaq Presario CQ40 313A
- 05-25· 2011年03月25日
- 05-25· 如何安装在您的康柏Evo
- 05-25· 康柏斯校园购物网康柏斯