另类加水印——根据明暗度分别加不同的水印


  1. package image;   

  2.   

  3. import java.awt.AlphaComposite;   

  4. import java.awt.Color;   

  5. import java.awt.Font;   

  6. import java.awt.Graphics;   

  7. import java.awt.Graphics2D;   

  8. import java.awt.Image;   

  9. import java.awt.image.BufferedImage;   

  10. import java.awt.image.ColorModel;   

  11. import java.awt.image.PixelGrabber;   

  12. import java.io.File;   

  13. import java.io.FileOutputStream;   

  14.   

  15. import javax.imageio.ImageIO;   

  16.   

  17. import com.sun.image.codec.jpeg.JPEGCodec;   

  18. import com.sun.image.codec.jpeg.JPEGImageEncoder;   

  19.   

  20. public class WaterMark {   

  21.   

  22.     /**  

  23.      * 获取指定矩形中的像素的矩阵  

  24.      *   

  25.      * @param imageSrc  

  26.      * @param startX  

  27.      * @param startY  

  28.      * @param w  

  29.      * @param h  

  30.      * @return  

  31.      */  

  32.     private int[] getPixArray(Image imageSrc, int startX, int startY,   

  33.             int w, int h) {   

  34.         int[] pix = new int[(w – startX) * (h – startY)];   

  35.            

  36.         /*下面是别人程序中的一段,我实在不明白为何要加这一段,因为我去掉也没有问题,加上还会报错*/  

  37.         PixelGrabber pg = null;   

  38.         try {   

  39.             pg = new PixelGrabber(imageSrc, startX, startY, w-startX, h-startY, pix, 0, w);   

  40.             if (pg.grabPixels() != true) {   

  41.                 try {   

  42.                     throw new java.awt.AWTException(“pg error” + pg.status());   

  43.                 } catch (Exception eq) {   

  44.                     eq.printStackTrace();   

  45.                 }   

  46.             }   

  47.         } catch (Exception ex) {   

  48.             ex.printStackTrace();   

  49.         }   

  50.         return pix;   

  51.     }   

  52.   

  53.     /**  

  54.      * 将1张图片和另1张图片的指定区域重合。可用于制作水印。图片的左上角坐标为0,0  

  55.      *   

  56.      * @param lightnessWaterImg  

  57.      *            颜色比较亮的水印图片,适合底色比较暗的情况  

  58.      * @param darknessWaterImg  

  59.      *            颜色比较暗的水印图片,适合底色比较亮的情况,如果不想区分,则输入null,平均灰度边界同时失效。  

  60.      * @param targetImg  

  61.      *            源图片  

  62.      * @param startX  

  63.      * @param startY  

  64.      * @param x  

  65.      * @param y  

  66.      * @param alpha  

  67.      *            透明度,0f为全透明,1f为完全不透明,0.5f为半透明  

  68.      * @param averageGray  

  69.      *            平均灰度边界(0-255),大于此值,则打暗的水印图片,小于此值则打亮的水印图片。  

  70.      *            默认值128。超过范围,按默认值进行。  

  71.      */  

  72.     private final void pressImage(String lightnessWaterImg,   

  73.             String darknessWaterImg, String targetImg, int startX, int startY,   

  74.             int x, int y, float alpha, float averageGray) {   

  75.         try {   

  76.             // 先判断亮水印和源文件的值是否为null,否则抛出异常   

  77.             if (lightnessWaterImg == null || lightnessWaterImg == “”  

  78.                     || targetImg == null || targetImg == “”) {   

  79.                 throw new Exception(“亮水印或者源图片的地址不能为空”);   

  80.             }    

  81.             // 再判断平均灰度边界是否越界   

  82.             if (averageGray>255||averageGray<0) {   

  83.                 averageGray = 128;   

  84.             }   

  85.                

  86.   

  87.             // 装载源图片   

  88.             File _file = new File(targetImg);   

  89.             // 图片装入内存   

  90.             BufferedImage src = ImageIO.read(_file);   

  91.             // 获取图片的尺寸   

  92.             int width = src.getWidth(null);   

  93.             int height = src.getHeight(null);   

  94.             // 根据源图片尺寸,设置预装载的一个图片,默认是RGB格式的   

  95.             BufferedImage image = new BufferedImage(width, height,   

  96.                     BufferedImage.TYPE_INT_RGB);   

  97.             Graphics2D graphics = image.createGraphics();   

  98.             // 绘制内存中的源图片至指定的矩形内   

  99.             graphics.drawImage(src, 00, width, height, null);   

  100.             // 在已经绘制的图片中加入透明度通道   

  101.             graphics.setComposite(AlphaComposite.getInstance(   

  102.                     AlphaComposite.SRC_ATOP, alpha));   

  103.                

  104.   

  105.             // 获取源图片中和设定的同样大小的区域内的像素集合   

  106.             int[] pixels = getPixArray(src, startX, startY, x, y);   

  107.   

  108.             //查询此集合的平均灰度   

  109.             float average = getAverageGrap(x-startX,y-startY,pixels);   

  110.   

  111.             // 如果平均灰度大于130,则说明此区域比较亮,否则则比较暗   

  112.             System.out.println(average);   

  113.   

  114.                

  115.             //装载水印图片所需参数   

  116.             File water;   

  117.             BufferedImage bufferwater;   

  118.                

  119.             // 根据设定的平均灰度边界来装载不同的水印   

  120.             if (darknessWaterImg == null||average>=averageGray) {   

  121.                 // 装载亮水印文件   

  122.                 water = new File(darknessWaterImg);   

  123.             }else{   

  124.                 // 装载暗水印文件   

  125.                 water = new File(lightnessWaterImg);   

  126.             }   

  127.             // 装入内存   

  128.             bufferwater = ImageIO.read(water);   

  129.                            

  130.             graphics.drawImage(bufferwater, startX, startY, x, y,   

  131.                     null);   

  132.             // 水印文件结束   

  133.             graphics.dispose();   

  134.             FileOutputStream out = new FileOutputStream(targetImg);   

  135.             JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);   

  136.             // 绘制新的文件   

  137.             encoder.encode(image);   

  138.             out.close();   

  139.                

  140.         } catch (Exception e) {   

  141.             e.printStackTrace();   

  142.         }   

  143.     }   

  144.            

  145.     /**  

  146.      * 查询某个区域的平均灰度  

  147.      * @param width  

  148.      * @param height  

  149.      * @param pixels  

  150.      * @return  

  151.      */  

  152.     private float getAverageGrap(int width,int height,int[] pixels){   

  153.         /* 下面是开始算这个区域的亮度了,灰度等同于亮度 */  

  154.         ColorModel colorModel = ColorModel.getRGBdefault();   

  155.         int i = 0;   

  156.         int j = 0;   

  157.         int k = 0;   

  158.         int r = 0;   

  159.         int g = 0;   

  160.         int b = 0;   

  161.         int gray = 0;   

  162.         float average = 0;// 平均灰度   

  163.         for (i = 0; i < height; i++) {   

  164.             for (j = 0; j < width; j++) {   

  165.                 // 定位像素点   

  166.                 k = i * width + j;   

  167.                 r = colorModel.getRed(pixels[k]);   

  168.                 g = colorModel.getGreen(pixels[k]);   

  169.                 b = colorModel.getBlue(pixels[k]);   

  170.   

  171.                 // 计算灰度值   

  172.                 gray = (r * 38 + g * 75 + b * 15) >> 7;   

  173.   

  174.                 average = average + gray;   

  175.             }   

  176.         }   

  177.         // 计算平均灰度   

  178.         average = average / ((i – 1) * (j – 1));   

  179.         return average;   

  180.     }   

  181.     public static void main(String[] args) {   

  182.         WaterMark waterMark = new WaterMark();   

  183.   

  184.         waterMark.pressImage(“F:\\Mine\\My Pictures\\素材\\w2.png”“F:\\Mine\\My Pictures\\素材\\w1.png”,   

  185.                 “F:\\Mine\\My Pictures\\素材\\2.jpg”5205009008000.5f, 50);   

  186.         System.out.print(“添加成功”);   

  187.     }   

  188.   

  189. }