java中ImageIO.write(bufferedImage输出图片时,图片的改变问题

来源:互联网 发布:淘宝客服大概多少工资 编辑:程序博客网 时间:2024/05/21 17:25

在编写图像二值化、灰度化的时候无意间发现在方法中使用ImageIO.write输出图像时仍然执行给bufferedImage赋值时候的语句,下面贴上代码:


package test;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import javax.imageio.ImageIO;public class test {public static void main(String[] args) throws IOException {// TODO Auto-generated method stub        BufferedImage bufferedImage = ImageIO.read(new File("D:/adt-bundle-windows-x86_64-20140321/workspace/test/img/test6.jpg"));                 BufferedImage bufferedImage2=grayimage( bufferedImage);        BufferedImage bufferedImage3=erzh( bufferedImage);//这里改变了bufferedImage2值                        ImageIO.write(bufferedImage, "jpg", new File("D:/adt-bundle-windows-x86_64-20140321/workspace/test/img/yuantu.jpg"));        ImageIO.write(bufferedImage2, "jpg", new File("D:/adt-bundle-windows-x86_64-20140321/workspace/test/img/huidutu.jpg"));        ImageIO.write(bufferedImage3, "jpg", new File("D:/adt-bundle-windows-x86_64-20140321/workspace/test/img/ezh.jpg"));}public static BufferedImage grayimage(BufferedImage bufferedImage){int h = bufferedImage.getHeight();    int w = bufferedImage.getWidth();   //BufferedImage bufferedImage2 = new BufferedImage(w, h, BufferedImage. TYPE_3BYTE_BGR );    for (int x = 0; x < w; x++)       {          for (int y = 0; y < h; y++)           {            int argb = bufferedImage.getRGB(x, y);          int r = (argb >> 16) & 0xFF;                  int g = (argb >> 8) & 0xFF;                  int b = (argb >> 0) & 0xFF;                  int grayPixel=(int)(r+g+b)/3;         //将各个颜色组合为rgb颜色值                int rgb = (grayPixel*256 + grayPixel)*256+grayPixel;                    if(rgb>8388608)  //rgb的最大值为8388608,因此当大于时候需要减去256*256*256                  {                        rgb = rgb - 16777216;                    }                                          bufferedImage.setRGB(x, y, rgb);         //bufferedImage2.setRGB(x, y, rgb);                                            }       }//return  bufferedImage2;return  bufferedImage;}public static int[][] huidutujuzhen(BufferedImage bufferedImage){//灰度化bufferedImage=grayimage(bufferedImage);int h = bufferedImage.getHeight();    int w = bufferedImage.getWidth();    //获取灰度矩阵    int[][]gray=new int[h][w];           for (int x = 0; x < w; x++)     {        for (int y = 0; y < h; y++)         {           int a = bufferedImage.getRGB(x, y);           gray[y][x]=a;                              }              }return gray;}public static BufferedImage erzh(BufferedImage bufferedImage){               int h = bufferedImage.getHeight();       int w = bufferedImage.getWidth();            int[][] gray =  huidutujuzhen( bufferedImage);      // BufferedImage bufferedImage2 = new BufferedImage(w, h, BufferedImage. TYPE_3BYTE_BGR );              // 效果较好的二值化算法                 int threshold = ostu(gray, w, h);                 System.out.print(threshold);           // BufferedImage binaryBufferedImage = ImageIO.read(new File("D:/adt-bundle-windows-x86-20130219/workspace/wenzi/src/huiduhua.jpg"));                 //  BufferedImage binaryBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);//最后一个参数就是二值化TYPE_BYTE_GRAY、、TYPE_3BYTE_BGR                           for (int x = 0; x < w; x++)                            {                              for (int y = 0; y < h; y++)                              {                              int gry=gray[y][x]&0xff;                                   if (gry > threshold)                                    {                                       gray[y][x]=0xFFFFFF;                                   }                                    else                                   {                                      gray[y][x]=0x000000;                                   }                                                                                        bufferedImage.setRGB(x, y, gray[y][x] );                               }                          }                                                          return bufferedImage;                                                  } //OTSU的中心思想是阈值T应使目标与背景两类的类间方差最大。取得合适二值化阀值的函数    public static int ostu(int[][] gray, int w, int h) {        int[] histData =new int[256];// new int[w * h];        // Calculate histogram        for (int x = 0; x < w; x++) {            for (int y = 0; y < h; y++) {                int red = 0xFF & gray[y][x];                histData[red]++;            }        }         // Total number of pixels        int total = w * h;         float sum = 0;   //总的灰度和,,,,,,可能有的灰度不存在histdata就越界了。        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//histData[t]为灰度为t的像素点的 个数,wB为已循环到的像素点和            if (wB == 0)                continue;             wF = total - wB; // Weight Foreground  wF剩余像素点            if (wF == 0)                break;             sumB += (float) (t * histData[t]);//灰度为t的的像素和             float mB = sumB / wB; // Mean Background  所循环到的灰度为t的和除以已经循环到的点的和            float mF = (sum - sumB) / wF; // Mean Foreground  sum为所有灰度值的和             // 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;    }}
会发现在输出图像的时候如果在灰度化后二值化改变bufferedImage的值,最后输出灰度图时候发现灰度图像也被二值化了,由此推断(不知是否正确,望大牛指点)在ImageIO.write输出图像时候仍然执行了一遍BufferedImage bufferedImage2=grayimage( bufferedImage);而此时的bufferedImage已经被二值化方法改变了,因此灰度图2会变成二值化图!

0 0
原创粉丝点击