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

標簽:水印 java   瀏覽(309)  日期:2008-08-28
  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. }  



-------------------------------------------------



  
Are you Bot? How you know that?ofcz no.