package com.ks.tools;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
/**
* @author 李英夫
* @ClassName CreateImg
* @date 2010-6-18 上午2:51:47
* @description
* 1.在生成的图片上输出文字
* 2.算法Scare和Node类提供,某吉大研究生,嘿嘿
*/
public class CreateImg {
private static final int INIT_X = 5; //初始X坐标
private static final int INIT_Y = 5; //初始Y坐标
private static final int LINE_HEIGHT = 5; //行高
private static final int PAINT_INIT_X = 0; //打印默认X坐标
private static final int PAINT_INIT_Y = 0; //打印默认Y坐标
private static final String FONT_FAMILY = "宋体"; //字体
private static final int FONT_WEIGHT = Font.PLAIN; //字体粗细
private static final Color FONT_COLOR = Color.BLACK; //字体颜色
private static final Color BACKGROUND = Color.WHITE; //背景颜色
private static final int IMAGE_COLOR_WEIGHT = BufferedImage.TYPE_INT_RGB; //表示一个图像,它具有合成整数像素的 8 位 RGB 颜色分量。
private static final String IMG_TYPE = "png"; //图片类型
/**
* 创建一个图片,在图片上写字
* @author 李英夫(2009-12-29 下午07:35:29)
* @param path 生成图片的路径
* @param texts 文字的集合
* @param fontSize 文字的大小
* @param textNum 每行文字的数量
* @throws Exception void
*/
public static void createIMG(String path, List<String> texts, int fontSize, int textNum)throws Exception{
int x = INIT_X;//文字显示的x轴坐标
int y = INIT_Y;//文字显示的y轴坐标
//行数
int lineNum = 0;
//先计算整张图片的高度和宽度
for (int i = 0; i < texts.size(); i++) {
lineNum += (int)Math.ceil(removeMark(texts.get(i)).length()*1.0/textNum*1.0);
}
int width = 2*x + fontSize*(textNum+2); //两个x的补白
//int height = (lineNum+1)*(fontSize+LINE_HEIGHT) + 2*y + LINE_HEIGHT; //两个y的补白
int height = lineNum*(fontSize+LINE_HEIGHT) + 2*y; //两个y的补白
File file = new File(path);
//设置字体和样式
Font font = new Font(FONT_FAMILY, FONT_WEIGHT, fontSize);
BufferedImage bi = new BufferedImage(width, height, IMAGE_COLOR_WEIGHT);
Graphics2D g2 = (Graphics2D) bi.getGraphics();
g2.setBackground(BACKGROUND);
g2.clearRect(PAINT_INIT_X, PAINT_INIT_Y, width, height);
g2.setPaint(FONT_COLOR);
g2.setFont(font);
FontRenderContext context = g2.getFontRenderContext();
for (int i = 0; i < texts.size(); i++) {
//行数
int linesPreTest = (int)Math.ceil(removeMark(texts.get(i)).length()*1.0/textNum*1.0) ;
for (int j = 0; j < linesPreTest; j++) {
String tempString = "";
//每次计算折行
if(j == linesPreTest-1)
tempString = texts.get(i).substring(j*textNum);
else
tempString = texts.get(i).substring(j*textNum, (j+1)*textNum);
//判断当前行有没有上、下标
double baseY = 0.0;
Rectangle2D bounds = font.getStringBounds(tempString, context);
double ascent = -bounds.getY();
baseY = y + ascent;
if(!isMark(tempString)){
g2.drawString(tempString, x, (int) baseY);
}else{
Scare s = new Scare();
s.parse(tempString);
List<Node> list = s.getList();
int xRay = x;
for (int k = 0; k < list.size(); k++) {
Node node = list.get(k);
float baseF = 0f;
if(null == node.getTag())baseF = 1f;
else if("sub".equals(node.getTag()))baseF = 1.2f;
else baseF = 1f/1.2f;
g2.drawString(node.getText(), (float)xRay*1.0f, (float)baseY*baseF);
xRay += getTxtLen(node.getText())*fontSize;
}
}
//纵坐标
y += fontSize+LINE_HEIGHT;
//横坐标
//x = INIT_X + fontSize + DOT;
x = INIT_X;
}
x = INIT_X;
}
ImageIO.write(bi, IMG_TYPE, file);
}
/**
* 是否存在上、下标的标签,存在返回true
* @param s
* @return
*/
private static boolean isMark(String s){
return (s.indexOf("<sub>") == -1) && (s.indexOf("<sup>") == -1) ? false : true;
}
/**
* 将标记替换掉
* @param s
* @return
*/
private static String removeMark(String s){
return s.replaceAll("<.*?>","");
}
/**
* 获得字符串真正的长度,分为双字节和单字节
* @param s
* @return
*/
private static double getTxtLen(String s){
return s.replaceAll("[^\\x00-\\xff]", "").length()/2.0 + s.replaceAll("[\\x00-\\xff]", "").length()*1.0;
}
public static void main(String[] args) throws Exception {
List<String> s = new ArrayList<String>();
s.add("A.a<sup>2</sup>+b<sup>2</sup>=c<sup>2</sup>===========H<sub>2</sub>O");
s.add("B.一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一!");
s.add("C.九十!");
s.add("D.一!");
createIMG("C:\\a.jpg",s,14,40);
String ssss = "Aaaa在aa工a";
System.out.println(getTxtLen(ssss));
}
}
package com.ks.tools;
import java.util.ArrayList;
import java.util.List;
public class Scare {
private int state = 0;
private int count = 0;
private boolean flag = true;
private String startTag = null;
private String endTag = null;
private List<Node> list = new ArrayList<Node>();
public boolean parse(String input) {
int length = input.length();
StringBuffer sb = new StringBuffer();
Node node = null;
for (int i = 0; i < length; i++) {
String str = input.substring(i, i + 1);
switch (state) {
case 0:
if (str.equals("<")) {
state = 2;
count++;
} else if (str.equals(">")) {
return false;
} else {
state = 1;
sb.append(str);
}
break;
case 1:
if (str.equals("<")) {
state = 2;
node = new Node();
node.setText(sb.toString());
list.add(node);
count++;
sb.delete(0, sb.length());
} else if (str.equals(">")) {
return false;
} else {
sb.append(str);
}
break;
case 2:
if (str.equals("<") || str.equals(">")) {
return false;
} else {
if (str.equals("/")) {
if (flag == true)
return false;
else {
state = 3;
}
} else {
if (flag == false)
return false;
else {
state = 3;
sb.append(str);
}
}
}
break;
case 3:
if (str.equals("<")) {
return false;
} else if (str.equals(">")) {
state = 4;
if (flag == true) {
startTag = sb.toString();
flag = false;
} else {
endTag = sb.toString();
flag = true;
if (check())
node.setTag(sb.toString());
else
return false;
}
count--;
sb.delete(0, sb.length());
} else {
sb.append(str);
}
break;
case 4:
if (str.equals("<") || str.equals(">")) {
return false;
} else {
state = 1;
sb.append(str);
}
break;
}
}
if ((flag == true) && check() && count == 0) {
node = new Node();
node.setText(sb.toString());
list.add(node);
sb.delete(0, sb.length());
return true;
}
return false;
}
private boolean check() {
return startTag.equals(endTag);
}
public List<Node> getList() {
return list;
}
public static void main(String args[]) {
Scare scare = new Scare();
String input = "ab<sub>c</sub>def<sup>g</sup>hi";
System.out.println(scare.parse(input));
List<Node> list = scare.getList();
for (Node node : list) {
System.out.println(node.getTag() + " " + node.getText());
}
}
}
package com.ks.tools;
public class Node {
private String tag = null;
private String text = null;
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
分享到:
相关推荐
在这个项目中,我们将会深入探讨如何使用`Graphics2D`来绘制复杂的图形,并将它们保存为图片文件。 首先,我们需要了解`Graphics2D`的基本用法。在Java中,图形绘制通常在`Component`或`Canvas`的`paint()`或`...
【作品名称】:基于Java Graphics2D生成各类圆形/椭圆公章、私章图片 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:...
使用Java Graphics2D类生成心跳曲线坐标图,一般用于在服务器端生成坐标对数据图片,示例可以参考这里:https://blog.csdn.net/youxijishu/article/details/124545372?spm=1001.2014.3001.5502
在Java编程中,有时我们需要将文字,特别是汉字,写入到图片中,这通常涉及到`Graphics2D`类的使用。然而,在实际操作过程中,可能会遇到一个常见的问题:汉字显示为方块乱码。这个问题通常是由于字体文件不支持或者...
在Java中,Graphics2D通常与AWT和Swing组件一起使用,用于绘制组件内部或自定义的图形。 本项目的核心是利用Graphics2D来绘制流程图,结合枚举(ENUM)来组织和管理流程图的各种元素,如线条类型、形状等。流程图是...
<br>import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; <br>import ...
5. 如果需要,也可以生成条形码,同样使用Graphics2D绘制条形码的线条和间隔。 6. 添加其他信息,如收件人和寄件人的地址、时间戳等,可以使用Graphics2D的文本绘制功能。 7. 最后,将整个打印单的内容保存为一个...
在这个项目中,我们可能就是用`BufferedImage`来存储和操作图片。 2. **Box Blur算法**: Box Blur是一种简单的模糊算法,它通过对图像进行多次平均滤波来实现模糊效果。该算法涉及将图像的每个像素值替换为其周围...
Java 使用 Servlet 动态生成图片 在 Web 应用中,经常需要动态生成图片,如实时股市行情、各种统计图等等。这种情况下,图片只能在服务器内存中动态生成并发送给用户,然后在浏览器中显示出来。本质上,浏览器向...
本文将详细讲解如何实现“圆角图片(可带边框)”的功能,以及如何使用名为“RoundedImageView-master”的代码包。 首先,让我们了解圆角图片的基本概念。在传统的矩形图片中,每个角落都是直角,而圆角图片则通过...
本文将深入探讨如何使用Java来生成图片,并结合打印功能,为开发者提供详细的实践指南。 首先,Java提供了多种库来帮助我们创建和处理图像。其中最常用的是Java Advanced Imaging (JAI) API和Java 2D API。JAI提供...
6. **创建图片**: 要将绘制的文字保存为图片,首先需要一个`BufferedImage`对象,然后使用`Graphics2D`的`create()`方法创建一个`Graphics2D`实例,进行绘制操作。最后,使用`ImageIO.write(BufferedImage img, ...
这里我们将深入探讨如何使用Java根据配置文件批量生成图片。 首先,要生成图片,我们需要理解Java中的图像处理库。Java标准库提供了一个名为`java.awt`和`javax.imageio`的包,它们包含了创建、显示和保存图像的...
对于开发和预览阶段,一些在线图片占位符服务如Placeholders.com提供了圆角图片选项,可以快速生成临时的圆角图片。 7.响应式设计: 在移动优先的设计理念下,圆角图片需要在不同设备和屏幕尺寸下保持一致的视觉...
网上找的缩略图生成方法都不够清晰,于是决定自己研究和改进生成缩略图方法。此方法压缩后的图片小,清晰度高,压缩速度快。5000张图片大概抽根烟的功夫就压缩完了。高清的哦。各种参数都是可配的,方便移植到自己...
在Java中给图片添加水印是一种常见的保护图片的方法,特别是在需要防止图片被盗用或者...要给图片添加水印,首先需要加载原始图片,然后创建一个Graphics2D对象来绘制水印。在绘制水印之后,将结果保存为一个新的文件。
在IT领域,验证码(CAPTCHA)是一...在提供的压缩包文件“图片验证码生成”中,可能包含了实现上述功能的源代码示例,你可以通过学习和理解这些代码,加深对Java生成图片验证码的理解,并根据实际需求进行调整和优化。
Java动态生成图片并把当前时间写在图片上是一项常见的需求,比如用于生成验证码、日志记录或者自定义的报告。这个任务涉及到Java图形处理、日期时间处理以及IO操作等多个方面。下面将详细介绍如何实现这个功能。 ...
我们将深入探讨这个主题,首先了解JavaBeans规范,然后讨论如何使用Java生成图片,最后分析给定的两个源代码文件`CreateImage.java`和`ImageBean.java`可能涉及的概念。 **JavaBeans规范:** JavaBeans是一种遵循...
在这个“jfreechart生成图片及导出pdf、excel”的主题中,我们将深入探讨如何利用JFreeChart来生成这些图表,并将其导出为PDF和Excel格式。 1. **JFreeChart基本使用** JFreeChart库提供了多种图表类型,包括...