另类加水印——根据明暗度分别加不同的水印
来源:互联网 发布:mac media player加速 编辑:程序博客网 时间:2024/06/09 23:05
公司里要求上传的照片都要加上公司的logo,统一打在又下角。但是,由于照片有暗有亮,因此logo分成了2种,1种是在比较亮的情况下打的,1种是在比较暗的情况下打的。这可把我害惨了,如何判断明暗度嘛。奋力Google了1天终于理解,于是写出了实现代码。
由于注释写的比较全,因此不再进行解释,里面也有测试方法,可以进行下测试。
由于注释写的比较全,因此不再进行解释,里面也有测试方法,可以进行下测试。
- package image;
- import java.awt.AlphaComposite;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Graphics;
- import java.awt.Graphics2D;
- import java.awt.Image;
- import java.awt.image.BufferedImage;
- import java.awt.image.ColorModel;
- import java.awt.image.PixelGrabber;
- import java.io.File;
- import java.io.FileOutputStream;
- import javax.imageio.ImageIO;
- import com.sun.image.codec.jpeg.JPEGCodec;
- import com.sun.image.codec.jpeg.JPEGImageEncoder;
- public class WaterMark {
- /**
- * 获取指定矩形中的像素的矩阵
- *
- * @param imageSrc
- * @param startX
- * @param startY
- * @param w
- * @param h
- * @return
- */
- private int[] getPixArray(Image imageSrc, int startX, int startY,
- int w, int h) {
- int[] pix = new int[(w - startX) * (h - startY)];
- /*下面是别人程序中的一段,我不是很理解了*/
- PixelGrabber pg = null;
- try {
- pg = new PixelGrabber(imageSrc, startX, startY, w-startX, h-startY, pix, 0, w-startX);
- if (pg.grabPixels() != true) {
- try {
- throw new java.awt.AWTException("pg error" + pg.status());
- } catch (Exception eq) {
- eq.printStackTrace();
- }
- }
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- return pix;
- }
- /**
- * 将1张图片和另1张图片的指定区域重合。可用于制作水印。图片的左上角坐标为0,0
- *
- * @param lightnessWaterImg
- * 颜色比较亮的水印图片,适合底色比较暗的情况
- * @param darknessWaterImg
- * 颜色比较暗的水印图片,适合底色比较亮的情况,如果不想区分,则输入null,平均灰度边界同时失效。
- * @param targetImg
- * 源图片
- * @param startX
- * @param startY
- * @param x
- * @param y
- * @param alpha
- * 透明度,0f为全透明,1f为完全不透明,0.5f为半透明
- * @param averageGray
- * 平均灰度边界(0-255),大于此值,则打暗的水印图片,小于此值则打亮的水印图片。
- * 默认值128。超过范围,按默认值进行。
- */
- private final void pressImage(String lightnessWaterImg,
- String darknessWaterImg, String targetImg, int startX, int startY,
- int x, int y, float alpha, float averageGray) {
- try {
- // 先判断亮水印和源文件的值是否为null,否则抛出异常
- if (lightnessWaterImg == null || lightnessWaterImg == ""
- || targetImg == null || targetImg == "") {
- throw new Exception("亮水印或者源图片的地址不能为空");
- }
- // 再判断平均灰度边界是否越界
- if (averageGray>255||averageGray<0) {
- averageGray = 128;
- }
- // 装载源图片
- File _file = new File(targetImg);
- // 图片装入内存
- BufferedImage src = ImageIO.read(_file);
- // 获取图片的尺寸
- int width = src.getWidth(null);
- int height = src.getHeight(null);
- // 根据源图片尺寸,设置预装载的一个图片,默认是RGB格式的
- BufferedImage image = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_RGB);
- Graphics2D graphics = image.createGraphics();
- // 绘制内存中的源图片至指定的矩形内
- graphics.drawImage(src, 0, 0, width, height, null);
- // 在已经绘制的图片中加入透明度通道
- graphics.setComposite(AlphaComposite.getInstance(
- AlphaComposite.SRC_ATOP, alpha));
- // 获取源图片中和设定的同样大小的区域内的像素集合
- int[] pixels = getPixArray(src, startX, startY, x, y);
- //查询此集合的平均灰度
- float average = getAverageGrap(x-startX,y-startY,pixels);
- // 如果平均灰度大于130,则说明此区域比较亮,否则则比较暗
- System.out.println(average);
- //装载水印图片所需参数
- File water;
- BufferedImage bufferwater;
- // 根据设定的平均灰度边界来装载不同的水印
- if (darknessWaterImg == null||average>=averageGray) {
- // 装载亮水印文件
- water = new File(darknessWaterImg);
- }else{
- // 装载暗水印文件
- water = new File(lightnessWaterImg);
- }
- // 装入内存
- bufferwater = ImageIO.read(water);
- graphics.drawImage(bufferwater, startX, startY, x-startX, y-startY,
- null);
- // 水印文件结束
- graphics.dispose();
- FileOutputStream out = new FileOutputStream(targetImg);
- JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
- // 绘制新的文件
- encoder.encode(image);
- out.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 查询某个区域的平均灰度
- * @param width
- * @param height
- * @param pixels
- * @return
- */
- private float getAverageGrap(int width,int height,int[] pixels){
- /* 下面是开始算这个区域的亮度了,灰度等同于亮度 */
- ColorModel colorModel = ColorModel.getRGBdefault();
- int i = 0;
- int j = 0;
- int k = 0;
- int r = 0;
- int g = 0;
- int b = 0;
- int gray = 0;
- float average = 0;// 平均灰度
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- // 定位像素点
- k = i * width + j;
- r = colorModel.getRed(pixels[k]);
- g = colorModel.getGreen(pixels[k]);
- b = colorModel.getBlue(pixels[k]);
- // 计算灰度值
- gray = (r * 38 + g * 75 + b * 15) >> 7;
- average = average + gray;
- }
- }
- // 计算平均灰度
- average = average / ((i - 1) * (j - 1));
- return average;
- }
- public static void main(String[] args) {
- WaterMark waterMark = new WaterMark();
- waterMark.pressImage("F://Mine//My Pictures//素材//w2.png", "F://Mine//My Pictures//素材//w1.png",
- "F://Mine//My Pictures//素材//2.jpg", 520, 500, 900, 800, 0.5f, 50);
- System.out.print("添加成功");
- }
- }
- 另类加水印——根据明暗度分别加不同的水印
- 加水印
- 加水印
- 加文字水印的。。图片的水印
- php根据背景图片深浅加水印
- 加文字水印和加图片水印的
- PHP 加水印
- 上传加水印
- jsp加图片水印
- 图片加水印类
- 图片加水印
- 生成缩略图加水印
- 图片加水印类
- ASP图片加水印
- 图片加水印
- 给图片加水印
- 图片加水印
- word加水印
- 时寒冰:中国房价下跌序幕刚刚拉开
- 一位软件工程师的6年总结
- 将N层集合对象自动转化为对应的.NET泛型对象(C++)
- linux的内核调度
- 进入注册表的一些常用命令
- 另类加水印——根据明暗度分别加不同的水印
- 在线聊天系统雏形总结(续)
- 转帖(chinaunix 的creator):我的嵌入式学习之路(二) linux button 驱动
- Linux系统下信号量的用法
- Ubuntu 更新源
- linux-2.6.13下madplay在S3C2440上移植的全过程详解
- 《华为真相》作者程东升再出新作 揭秘“百度奇迹”
- Using Moodle
- The Visualization Handbook