import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.springframework.util.StringUtils;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.*;
import java.io.*;
import java.util.Iterator;
/**
* @author :cw
* @date :Created in 2020/7/24 下午5:38
* @description:
* @modified By:
* @version: $
*/
public class TestImages {
private static String FONT_NAME = "微软雅黑";
private static int FONT_STYPE = Font.BOLD;
private static String outputNameStyle = ".png";
private static Color FONT_COLOR = Color.BLACK;
private static float ALPHA = 0.8F;
private static String imageOriginPath = "/Library/java/aliyunprojects/continue-service/src/main/resources/name.jpg";
private static String imageNewPath = "/Library/java/aliyunprojects/continue-service/src/main/resources/images/";
private static String txtFilePath = "/Library/java/aliyunprojects/continue-service/src/main/resources/names.txt";
public static void main(String[] args) {
File file = new File(imageOriginPath);
OutputStream os = null;
// 1、转化图片文件为缓冲流文件
BufferedImage image = getImage(file);
if(StringUtils.isEmpty(image)) {
return;
}
// 2、根据背景图片规格创建新的缓冲流图片
int width = image.getWidth(null);
int height = image.getHeight(null);
System.out.println("图片的宽度是:" + width + ",高度是:" + height);
BufferedImage bufferImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 3、读取txt文件的内容,获取list数组,循环生成图片
List namesList = getReadFileNames();
for (int i = 0; i < namesList.getItemCount(); i++) {
// 3.1、获取基础信息
int Y = 140;
int FONT_SIZE = 400;
String name = namesList.getItem(i);
String logoFileName = name + outputNameStyle;
String regex = "^[a-z0-9A-Z]+$";
// 3.2、调整位置,防止出现英文名字水平位置特殊调整
Boolean result = name.matches(regex);
System.out.println("正在绘制名字为" + name + "的图片。。。,正则比较的结果是:" + result);
if (result) {
FONT_SIZE = 340;
Y = 130;
if ("xxxxx".equals(name)) {
FONT_SIZE = 315;
}
}
// 3.3、根据原始背景图绘制新图片
Graphics2D g = bufferImage.createGraphics();
g.drawImage(image, 0, 0, width, height, null);
g.setFont(new Font(FONT_NAME, FONT_STYPE, FONT_SIZE));
g.setColor(FONT_COLOR);
// 3.4、获取文字的属性信息
int width1 = FONT_SIZE * getTextLength(name);
int height1 = FONT_SIZE;
System.out.println("文字的长度是:" + width1 + "高度是:" + height1);
// 3.5、动态设置文字在新图中的位置
int widthDiff = width - width1;
int x = widthDiff / 2;
int y = Y;
if (result) {
x = getXByEnglishName(name);
}
try {
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));
g.drawString(namesList.getItem(i), x, y + FONT_SIZE);
g.dispose();
os = new FileOutputStream( imageNewPath + logoFileName);
JPEGImageEncoder en = JPEGCodec.createJPEGEncoder(os);
en.encode(bufferImage);
}catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
/**
* 获取中文文字长度
* @param text
* @return
*/
public static int getTextLength(String text) {
int length = text.length();
for (int i = 0; i < text.length(); i++) {
String s = String.valueOf(text.charAt(i));
if (s.getBytes().length > 1) {
length++;
}
}
length = length % 2 == 0 ? length / 2 : length / 2 + 1;
return length;
}
/**
* 读入TXT文件
*/
public static List getReadFileNames() {
List arrays = new List();
String pathname = txtFilePath;
try (FileReader reader = new FileReader(pathname);
BufferedReader br = new BufferedReader(reader)
) {
String line;
//网友推荐更加简洁的写法
while ((line = br.readLine()) != null) {
arrays.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return arrays;
}
/**
* 修改图片颜色空间
* @param raster
* @return
*/
private static BufferedImage createJPEG4(Raster raster) {
int w = raster.getWidth();
int h = raster.getHeight();
byte[] rgb = new byte[w * h * 3];
//彩色空间转换
float[] Y = raster.getSamples(0, 0, w, h, 0, (float[]) null);
float[] Cb = raster.getSamples(0, 0, w, h, 1, (float[]) null);
float[] Cr = raster.getSamples(0, 0, w, h, 2, (float[]) null);
float[] K = raster.getSamples(0, 0, w, h, 3, (float[]) null);
for (int i = 0, imax = Y.length, base = 0; i < imax; i++, base += 3) {
float k = 220 - K[i], y = 255 - Y[i], cb = 255 - Cb[i],
cr = 255 - Cr[i];
double val = y + 1.402 * (cr - 128) - k;
val = (val - 128) * .65f + 128;
rgb[base] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
: (byte) (val + 0.5);
val = y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128) - k;
val = (val - 128) * .65f + 128;
rgb[base + 1] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
: (byte) (val + 0.5);
val = y + 1.772 * (cb - 128) - k;
val = (val - 128) * .65f + 128;
rgb[base + 2] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff
: (byte) (val + 0.5);
}
raster = Raster.createInterleavedRaster(new DataBufferByte(rgb, rgb.length), w, h, w * 3, 3, new int[]{0, 1, 2}, null);
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorModel cm = new ComponentColorModel(cs, false, true, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
return new BufferedImage(cm, (WritableRaster) raster, true, null);
}
/**
* 特殊姓名处理
* @param name
* @return
*/
public static int getXByEnglishName(String name) {
int x = 130;
switch (name) {
case "xxxx":
x = 170;
break;
case "xxx":
x = 415;
break;
case "xxx":
x = 345;
break;
case "xxx":
x = 435;
break;
case "xxxx":
x = 165;
break;
case "xxxx":
x = 295;
break;
case "xxxx":
x = 290;
break;
case "xxx":
x = 96;
break;
}
return x;
}
/**
* 获取Image 主要为了解决图片颜色空间问题 CMYK和RGB两种
* @param file
* @return
*/
public static BufferedImage getImage(File file) {
BufferedImage image = null;
try {
image = ImageIO.read(new FileInputStream(file));
} catch (Exception e) {
// 1、针对颜色空间产生的问题去做处理
try {
ImageInputStream input = ImageIO.createImageInputStream(file);
Iterator readers = ImageIO.getImageReaders(input);
if (readers == null || !readers.hasNext()) {
throw new RuntimeException("1 No ImageReaders found");
}
ImageReader reader = (ImageReader) readers.next();
reader.setInput(input);
String format = reader.getFormatName();
if ("JPEG".equalsIgnoreCase(format) || "JPG".equalsIgnoreCase(format)) {
try {
// 尝试读取图片 (包括颜色的转换).
image = reader.read(0); //RGB
} catch (IIOException e2) {
// 读取Raster (没有颜色的转换).
Raster raster = reader.readRaster(0, null);//CMYK
image = createJPEG4(raster);
}
}
} catch (Exception e1) {
return null;
}
}
return image;
}
}
java根据背景图批量生成带有名字新图片多种格式(兼容RGB和CMYK两种颜色空间)
最新推荐文章于 2021-11-21 21:32:19 发布