package com.rdss.common.util;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.apache.http.entity.ContentType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.*;
/**
* 照片处理函数
*/
public class ImageConfig {
/**
* File文件转MultipartFile文件
* @param file:file文件
* @return
* @throws IOException
*/
public static MultipartFile file2MultipartFile(File file) throws IOException {
FileInputStream fileInputStream = new FileInputStream(file);
// MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream)
// 其中originalFilename,String contentType 旧名字,类型 可为空
// ContentType.APPLICATION_OCTET_STREAM.toString() 需要使用HttpClient的包
return new MockMultipartFile("copy"+file.getName(),file.getName(), ContentType.APPLICATION_OCTET_STREAM.toString(),fileInputStream);
}
/**
* MultipartFile文件转File文件
* @param multipartFile:源MultipartFile文件
* @param basePath:保存文件的基础路径
* @param temFilePath:临时file路径
* @return
* @throws IOException
*/
public static File multipartFile2File(MultipartFile multipartFile, String basePath, String temFilePath) throws IOException{
File file = new File(basePath,temFilePath);
multipartFile.transferTo(file);
// 操作完上的文件 需要删除在根目录下生成的文件
return file;
}
/**
* 通过读取文件并获取其width及height的方式,来判断判断当前文件是否图片,这是一种非常简单的方式。
*
* @param imageFile
* @return
*/
public static boolean isImage(File imageFile) {
if (!imageFile.exists()) {
return false;
}
Image img = null;
try {
img = ImageIO.read(imageFile);
if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
return false;
}
return true;
} catch (Exception e) {
return false;
} finally {
img = null;
}
}
/**
* 给图片添加水印、可设置水印图片旋转角度
* @param iconPath 水印图片路径
* @param srcImgPath 源图片路径
* @param targerPath 目标图片路径
* @param degree 水印图片旋转角度
* @param width 宽度(与左相比)
* @param height 高度(与顶相比)
* @param clarity 透明度(小于1的数)越接近0越透明
*/
public static void waterMarkImageByIcon(String iconPath, String srcImgPath,
String targerPath, Integer degree, Integer width, Integer height,
float clarity) {
OutputStream os = null;
try {
Image srcImg = ImageIO.read(new File(srcImgPath));
System.out.println("width:" + srcImg.getWidth(null));
System.out.println("height:" + srcImg.getHeight(null));
BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
// 得到画笔对象
Graphics2D g = buffImg.createGraphics();
// 设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(
srcImg.getScaledInstance(srcImg.getWidth(null),
srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
null);
if (null != degree) {
// 设置水印旋转
g.rotate(Math.toRadians(degree),
(double) buffImg.getWidth() / 2,
(double) buffImg.getHeight() / 2);
}
// 水印图象的路径 水印一般为gif或者png的,这样可设置透明度
ImageIcon imgIcon = new ImageIcon(iconPath);
// 得到Image对象。
Image img = imgIcon.getImage();
float alpha = clarity; // 透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
// 表示水印图片的位置
g.drawImage(img, width, height, null);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
g.dispose();
os = new FileOutputStream(targerPath);
// 生成图片
ImageIO.write(buffImg, "JPG", os);
System.out.println("添加水印图片完成!");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != os)
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 给图片添加水印、可设置水印图片旋转角度
* @param logoText 水印文字
* @param srcImgPath 源图片路径
* @param targerPath 目标图片路径
* @param degree 水印图片旋转角度
* @param width 宽度(与左相比)
* @param height 高度(与顶相比)
* @param clarity 透明度(小于1的数)越接近0越透明
*/
public static void waterMarkByText(String logoText, String srcImgPath,
String targerPath, Integer degree, Integer width, Integer height,
Float clarity) {
// 主图片的路径
InputStream is = null;
OutputStream os = null;
try {
Image srcImg = ImageIO.read(new File(srcImgPath));
BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
// 得到画笔对象
// Graphics g= buffImg.getGraphics();
Graphics2D g = buffImg.createGraphics();
// 设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(
srcImg.getScaledInstance(srcImg.getWidth(null),
srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
null);
if (null != degree) {
// 设置水印旋转
g.rotate(Math.toRadians(degree),
(double) buffImg.getWidth() / 2,
(double) buffImg.getHeight() / 2);
}
// 设置颜色
g.setColor(Color.red);
// 设置 Font
g.setFont(new Font("宋体", Font.BOLD, 30));
float alpha = clarity;
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
// 第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y) .
g.drawString(logoText, width, height);
g.dispose();
os = new FileOutputStream(targerPath);
// 生成图片
ImageIO.write(buffImg, "JPG", os);
System.out.println("添加水印文字完成!");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != is)
is.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (null != os)
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 缩放图片(压缩图片质量,改变图片尺寸) 若原图宽度小于新宽度,则宽度不变!
* //5M 边压缩15,画质压缩50
* //30K 边压缩50,画质压缩50
* 可以规定由15开始,每增加150kb,长宽的压缩比减一
* @param originalFile
* 原图片路径地址
* @param resizedFile
* 压缩后输出路径地址
* @param lengthComp
* 边长压缩比,80相当于压缩到原长度的80%
* @param quality
* 图片质量参数 7 相当于70%质量
*/
public static void imageResize(File originalFile, File resizedFile, int lengthComp, int quality)
throws IOException {
if (quality<1||quality > 100) {
throw new IllegalArgumentException("图片质量需设置在1-9范围");
}
if (lengthComp<1||lengthComp>100) {
throw new IllegalArgumentException("图片长款压缩比需设置在1-99范围");
}
System.out.println("lengthComp is "+lengthComp+",quality is "+quality);
ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
Image i = ii.getImage();
Image resizedImage = null;
int iWidth = i.getWidth(null);
int iHeight = i.getHeight(null);
System.out.println("width is :"+iWidth +", height is :"+iHeight);
resizedImage = i.getScaledInstance((iWidth*lengthComp) / 100, (iHeight*lengthComp) / 100, Image.SCALE_SMOOTH);
// 此代码确保加载图像中的所有像素
Image temp = new ImageIcon(resizedImage).getImage();
// 创建缓冲图像
BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB);
// 将图像复制到缓冲图像
Graphics g = bufferedImage.createGraphics();
// 清除背景并绘制图像。
g.setColor(Color.white);
g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
g.drawImage(temp, 0, 0, null);
g.dispose();
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);
// 将jpeg写入文件
FileOutputStream out = new FileOutputStream(resizedFile);
// 将图像编码为jpeg数据流
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
param.setQuality( (quality/100.0f), true);
encoder.setJPEGEncodeParam(param);
encoder.encode(bufferedImage);
//out流刷新并关闭
out.flush();
out.close();
System.out.println("压缩后width is :"+temp.getWidth(null)+",height is : "+temp.getHeight(null));
}
public static void main(String[] args) throws IOException {
// waterMarkImageByIcon("D:\\水印图片.png", "D:\\图片.png", "D:\\目标图片.png", 10, 100, 100, 1F);
//waterMarkByText("电航", "D:\\图片.png", "D:\\图片2.jpg", 3, 30, 30, 1F);
// 需要压缩的图片地址 aaa.jpg为需要压缩的图片
File customaryFile = new File("E://testimg//pp.jpg");
if(customaryFile.length()>(5*1024*1024)){
return;
}
if(customaryFile.length()<(30*1024)){
return;
}
long lengthComp = customaryFile.length()/(1024*150);
// 压缩过后输出的路径地址 ddd.jpg 可进行设置为任意名称
File compressAfter = new File("E://testimg//"+System.currentTimeMillis()+".jpg");
long begintime = System.currentTimeMillis();
ImageConfig.imageResize(customaryFile, compressAfter,(50- (int)lengthComp), 5);
//5M 边压缩15,画质压缩5
//30K 边压缩50,画质压缩5
long end = System.currentTimeMillis();
System.out.println("使用时长:"+(end-begintime));
}
}
java 照片处理函数 工具类(水印、压缩)(参考一些文章,自己整理使用)
于 2022-04-25 09:55:24 首次发布