import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class ImageAddLogo {
/**
* @param srcImgPath 源图片路径
* @param tarImgPath 保存的图片路径
* @param waterMarkContent 水印内容
* @param markContentColor 水印颜色
* @param font 水印字体
*/
public void addWaterMark(String srcImgPath, String tarImgPath, String waterMarkContent,Color markContentColor,Font font) {
try {
// 读取原图片信息
File srcImgFile = new File(srcImgPath);//得到文件
Image srcImg = ImageIO.read(srcImgFile);//文件转化为图片
int srcImgWidth = srcImg.getWidth(null);//获取图片的宽
int srcImgHeight = srcImg.getHeight(null);//获取图片的高
// 加水印
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bufImg.createGraphics();
//透明要是生成的图片背景透明,必须加上这段代码-------------------------
bufImg = g.getDeviceConfiguration()
.createCompatibleImage(srcImgWidth, srcImgHeight, Transparency.BITMASK);
g.dispose();
g = bufImg.createGraphics();
//透明结束-------------------------------------------------------------------------------------
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
g.setColor(markContentColor); //根据图片的背景设置水印颜色
g.setFont(font); //设置字体
//设置水印的坐标
int x = srcImgWidth - getWatermarkLength(waterMarkContent, g);
int y = srcImgHeight - getWatermarkLength(waterMarkContent, g);
g.drawString(waterMarkContent,80,srcImgHeight-10); //画出水印
g.dispose();
// 输出图片
FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
ImageIO.write(bufImg, "png", outImgStream);
System.out.println("添加水印完成");
outImgStream.flush();
outImgStream.close();
} catch (Exception e) {
// TODO: handle exception
}
}
public int getWatermarkLength(String waterMarkContent, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
}
/**
* 改变png图片的透明度
* @param srcImageFile 源图像地址
* @param descImageDir 输出图片的路径和名称
* @param alpha 输出图片的透明度1-10
*/
public static void setAlpha(String srcImageFile, String descImageDir,int alpha) {
try {
//读取图片
FileInputStream stream = new FileInputStream(new File(srcImageFile));// 指定要读取的图片
// 定义一个字节数组输出流,用于转换数组
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] data =new byte[1024];// 定义一个1K大小的数组
while (stream.read(data) != -1) {
os.write(data);
}
ImageIcon imageIcon = new ImageIcon(os.toByteArray());
BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver());
//判读透明度是否越界
if (alpha < 0) {
alpha = 0;
} else if (alpha > 10) {
alpha = 10;
}
// 循环每一个像素点,改变像素点的Alpha值
for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) {
for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) {
int rgb = bufferedImage.getRGB(j2, j1);
rgb = ((alpha * 255 / 10) << 24) | (rgb & 0x00ffffff);
bufferedImage.setRGB(j2, j1, rgb);
}
}
g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
// 生成图片为PNG
ImageIO.write(bufferedImage, "png", new File(descImageDir));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws FileNotFoundException, IOException {
//setAlpha("C:\\Users\\zjadmin\\Desktop\\图片\\1t.png","C:\\Users\\zjadmin\\Desktop\\图片\\1t.png",0);
Font font = new Font("微软雅黑", Font.PLAIN, 18); //水印字体
String srcImgPath="C:\\Users\\zjadmin\\Desktop\\logo.png"; //源图片地址
String tarImgPath="C:\\Users\\zjadmin\\Desktop\\图片\\222t.png"; //待存储的地址
String waterMarkContent="2435454434"; //水印内容
Color color=new Color(255,255,255); //水印图片色彩以及透明度
new ImageAddLogo().addWaterMark(srcImgPath, tarImgPath,waterMarkContent, color,font);
/*File testDataDir = new File(tarImgPath);//去噪
BufferedImage textImage =ImageIO.read(new FileInputStream(testDataDir));
BufferedImage gray = gray(textImage);//灰度化
BufferedImage image = transparentImage(tarImgPath, 0);
ImageIO.write(image, "png", new File(tarImgPath2));*/
}
public static BufferedImage cleanImage(BufferedImage bufferedImage)throws IOException{
int h = bufferedImage.getHeight();
int w = bufferedImage.getWidth();
// 灰度化
int[][] gray = new int[w][h];
for (int x = 0; x < w; x++){
for (int y = 0; y < h; y++){
int argb = bufferedImage.getRGB(x, y);
// 图像加亮(调整亮度识别率非常高)
int r = (int) (((argb >> 16) & 0xFF) * 1.1 + 30);
int g = (int) (((argb >> 8) & 0xFF) * 1.1 + 30);
int b = (int) (((argb >> 0) & 0xFF) * 1.1 + 30);
if (r >= 255){
r = 255;
}
if (g >= 255){
g = 255;
}
if (b >= 255){
b = 255;
}
gray[x][y] = (int) Math.pow((Math.pow(r, 2.2) * 0.2973 + Math.pow(g, 2.2)* 0.6274 + Math.pow(b, 2.2) * 0.0753), 1 / 2.2);
}
}
// 二值化
int threshold = ostu(gray, w, h);
BufferedImage binaryBufferedImage = new BufferedImage(w, h,BufferedImage.TYPE_BYTE_BINARY);
for (int x = 0; x < w; x++){
for (int y = 0; y < h; y++){
if (gray[x][y] > threshold){
gray[x][y] |= 0x00FFFF;
} else{
gray[x][y] &= 0xFF0000;
}
binaryBufferedImage.setRGB(x, y, gray[x][y]);
}
}
return binaryBufferedImage;
}
public static int ostu(int[][] gray, int w, int h){
int[] histData = new int[w * h];
// Calculate histogram
for (int x = 0; x < w; x++){
for (int y = 0; y < h; y++){
int red = 0xFF & gray[x][y];
histData[red]++;
}
}
// Total number of pixels
int total = w * h;
float sum = 0;
for (int t = 0; t < 256; t++)
sum += t * histData[t];
float sumB = 0;
int wB = 0;
int wF = 0;
float varMax = 0;
int threshold = 0;
for (int t = 0; t < 256; t++){
wB += histData[t]; // Weight Background
if (wB == 0)
continue;
wF = total - wB; // Weight Foreground
if (wF == 0)
break;
sumB += (float) (t * histData[t]);
float mB = sumB / wB; // Mean Background
float mF = (sum - sumB) / wF; // Mean Foreground
// Calculate Between Class Variance
float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);
// Check if new maximum found
if (varBetween > varMax){
varMax = varBetween;
threshold = t;
}
}
return threshold;
}
//图片灰度,黑白
public static BufferedImage gray(BufferedImage src) {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op = new ColorConvertOp(cs, null);
src = op.filter(src, null);
return src;
}
/**
* 设置源图片为背景透明,并设置透明度
* @param srcImageFile 源图片
* @param alpha 透明度 (0-10依次不透明)
*/
public static BufferedImage transparentImage(String srcImageFile,int alpha) {
BufferedImage bufferedImage=null;
try {
//读取图片
FileInputStream stream = new FileInputStream(new File(srcImageFile));// 指定要读取的图片
// 定义一个字节数组输出流,用于转换数组
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] data =new byte[1024];// 定义一个1K大小的数组
while (stream.read(data) != -1) {
os.write(data);
}
ImageIcon imageIcon = new ImageIcon(os.toByteArray());
bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver());
//判读透明度是否越界
if (alpha < 0) {
alpha = 0;
} else if (alpha > 10) {
alpha = 10;
}
int c = bufferedImage.getRGB(3, 3);
// 循环每一个像素点,改变像素点的Alpha值
for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) {
for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) {
int rgb = bufferedImage.getRGB(j2, j1);
if(c==rgb){
rgb = rgb & 0x00ffffff;
}else{
rgb = ((alpha * 255 / 10) << 24) | (rgb & 0x00ffffff);
}
bufferedImage.setRGB(j2, j1, rgb);
}
}
g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
} catch (Exception e) {
e.printStackTrace();
}finally {
return bufferedImage;
}
}
}