.NET版:https://my.oschina.net/HJCui/blog/804981
1.文本画在图片上,自动换行
public static void textToImage(String str) {
try {
int width = 642;
int height = 377;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// Font font = Loadfont.loadFont("C:/华康瘦金体W3.TTF", 38);
Font font = Loadfont.Font();
Graphics g = image.getGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, width, height);
g.setFont(font);
Color c = new Color(106, 106, 106);
g.setColor(c);
int fontHeight = (int) font.getSize2D();
// 得到当前的font metrics
FontMetrics metrics = g.getFontMetrics();
int StrPixelWidth = metrics.stringWidth(str); // 字符串长度(像素) str要打印的字符串
int lineSize = (int) Math.ceil(StrPixelWidth * 1.0 / width);// 算出行数
// int lineNum = (int) Math.ceil(StrPixelWidth * 1.0 / lineSize);
// Rectangle2D bounds = metrics.getStringBounds(str, null);
// int widthInPixels = (int) bounds.getWidth();
System.out.println(StrPixelWidth + "---:");
if (width < StrPixelWidth) {// 页面宽度(width)小于 字符串长度
StringBuilder sb = new StringBuilder();// 存储每一行的字符串
int j = 0;
int tempStart = 0;
String tempStrs[] = new String[lineSize];// 存储换行之后每一行的字符串
for (int i1 = 0; i1 < str.length(); i1++) {
char ch = str.charAt(i1);
sb.append(ch);
Rectangle2D bounds2 = metrics.getStringBounds(sb.toString(), null);
int tempStrPi1exlWi1dth = (int) bounds2.getWidth();
if (tempStrPi1exlWi1dth > width) {
tempStrs[j++] = str.substring(tempStart, i1);
tempStart = i1;
sb.delete(0, sb.length());
sb.append(ch);
}
if (i1 == str.length() - 1) {// 最后一行
tempStrs[j] = str.substring(tempStart);
}
}
for (int i = 0; i < tempStrs.length; i++) {
g.drawString(tempStrs[i], 0, (fontHeight + 5) * (i + 1));
}
}
else {
g.drawString(str, 0, fontHeight);
}
File outputfile = new File("c:/saved.png");
ImageIO.write(image, "png", outputfile);
g.dispose();
} catch (IOException e) {
e.printStackTrace();
}
}
自定义字体
import java.awt.Font;
import java.io.File;
import java.io.FileInputStream;
/**
* @Description TODO
* @author hjcui
* @date 2016年12月9日下午4:46:53
* @version V1.0
*/
public class Loadfont {
public static Font loadFont(String fontFileName, float fontSize) // 第一个参数是外部字体名,第二个是字体大小
{
try
{
File file = new File(fontFileName);
FileInputStream fis = new FileInputStream(file);
Font dynamicFont = Font.createFont(Font.TRUETYPE_FONT, fis);
Font dynamicFontPt = dynamicFont.deriveFont(fontSize);
fis.close();
return dynamicFontPt;
} catch (Exception e)// 异常处理
{
e.printStackTrace();
return new java.awt.Font("宋体", Font.PLAIN, 14);
}
}
public static java.awt.Font Font() {
String root = System.getProperty("user.dir");// 项目根目录路径
Font font = Loadfont.loadFont(root + "/data/华康瘦金体W3.TTF", 38f);// 调用
return font;// 返回字体
}
}
测试
public static void main(String[] arg) {
String str = "张家口市地处京晋冀蒙交界处,距北京约180公里,这里地势险要,有“塞外山城”之称。冬季白雪皑皑,一片北国风光,山上积雪数尺,整冬不化,是滑雪旅游的天然胜地。全市地势西北高、东南低,阴山山脉横贯中部,将全市划分为坝上、坝下两个自然地理区域。坝上地区地势......";
// textToImage(str);
textToImage2(str);
}
效果图(放大锯齿明显)
2. 锯齿优化
// 抗锯齿
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
// g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
// g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
// g2.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST, 140);
// g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
// g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
只需要第一行就可以有效减小锯齿情况,
效果图
3.压缩图片
效果好了,文件大了。
压缩图片
package com.lotour.stringToImage;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import javax.swing.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.Kernel;
import java.awt.image.ConvolveOp;
/**
* @Description TODO
* @author hjcui
* @date 2016年12月12日上午11:35:44
* @version V1.0
*/
public class ImageUtil {
public static void resize(File originalFile, File resizedFile,
int newWidth, float quality) throws IOException {
if (quality > 1) {
throw new IllegalArgumentException(
"Quality has to be between 0 and 1");
}
ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
Image i = ii.getImage();
Image resizedImage = null;
int iWidth = i.getWidth(null);
int iHeight = i.getHeight(null);
if (iWidth > iHeight) {
resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight)
/ iWidth, Image.SCALE_SMOOTH);
} else {
resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight,
newWidth, Image.SCALE_SMOOTH);
}
// This code ensures that all the pixels in the image are loaded.
Image temp = new ImageIcon(resizedImage).getImage();
// Create the buffered image.
BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null),
temp.getHeight(null), BufferedImage.TYPE_INT_RGB);
// Copy image to buffered image.
Graphics g = bufferedImage.createGraphics();
// Clear background and paint the image.
g.setColor(Color.white);
g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
g.drawImage(temp, 0, 0, null);
g.dispose();
// Soften.
float softenFactor = 0.05f;
float[] softenArray = {0, softenFactor, 0, softenFactor,
1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0};
Kernel kernel = new Kernel(3, 3, softenArray);
ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
bufferedImage = cOp.filter(bufferedImage, null);
// Write the jpeg to a file.
FileOutputStream out = new FileOutputStream(resizedFile);
// Encodes image as a JPEG data stream
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
param.setQuality(quality, true);
encoder.setJPEGEncodeParam(param);
encoder.encode(bufferedImage);
}
// Example usage
public static void main(String[] args) throws IOException {
File originalImage = new File("C:\\saved_g2.png");
resize(originalImage, new File("c:\\1207-0.jpg"), 642, 0.7f);
resize(originalImage, new File("c:\\1207-1.jpg"), 642, 1f);
}
}
压缩后图片大小
1207-0.jpg效果图
图片放大后噪点多了一些,暂时可以接受。
完。