1. 程式人生 > >java 圖片操作技術之RGB的獲取

java 圖片操作技術之RGB的獲取


/**
 * 名詞解釋:
 * 飽和度是指色彩的鮮豔程度,也稱色彩的純度。
 * 灰度:使用黑色調錶示物體,即用黑色為基準色,不同的飽和度的黑色來顯示影象。
 * 畫素:如同攝影的相片一樣,數碼影像也具有連續性的濃淡階調,我們若把影像放大數倍,會發現這些連續色調其實是由許多色彩相近的小方點所組成,
 * 這些小方點就是構成影像的最小單元——畫素。是解析度的尺寸單位。
 * 畫素是基本原色素及其灰度的基本編碼。我們看到的數字圖片是有一個二維的畫素矩陣組成。
 * 畫素在計算機中通常用3個位元組24位儲存,如16-23 位表示紅色(R)分量,8-15 位表示綠色(G)分量,0-7 位表示藍色(B)分量;
 * 當圖片尺寸以畫素為單位時,每一釐米等於28畫素,比如15*15釐米長度的圖片,等於420*420畫素的長度。 
 * 一個畫素所能表達的不同顏色數取決於位元每畫素(BPP)。如8bpp[2^8=256色, 灰度影象]、16bpp[2^16=65536色,稱為高彩色]、24bpps[2^24=16777216色,稱為真彩色]。
 *  解析度:影象總畫素的多少,稱為影象解析度。
 *  RGB: 顏色模型,是將顏色表示成數字形式的模型,或者說是一種記錄影象顏色的方式。詳情百度
 *  
 *  下列程式碼是將一個圖片分解成R,G,B三種色彩灰度圖片的演算法
 * 也可參考原著為:http://blog.csdn.net/luoweifu/article/details/8042494
 * 
 */
package test;
 
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
 
import javax.imageio.ImageIO;
 
public class MyImage {
    // 將圖片分解為R,G,B三種灰度圖片
    /**
     * 
     * @param filePath 原圖片路徑
     * @param newFilePath 您想要生成的圖片路徑
     * @param type 選擇生成型別1為R,2G,3為B
     */
    public static void analyseRGB(String filePath, String newFilePath, int type) {
        OutputStream output = null;
        try {
            BufferedImage img = ImageIO.read(new File(filePath));
            int imageType = img.getType();// 獲取圖片型別
            int width = img.getWidth();// 獲取圖片寬度
            int height = img.getHeight();// 獲取圖片高度
            int startX = 0;// 開始的橫座標
            int startY = 0;// 開始的縱座標
            int offset = 0;// 偏移量
            int scansize = width;// 掃描間距
            int dd = width - startX;// 被遍歷的寬度間距
            int hh = height - startY;// 被遍歷的高度間距
            int x0 = width / 2;// 橫向中間點
            int y0 = height / 2;// 縱向中間點
            System.out.println("dd:" + dd + " hh:" + hh);
            System.out.println("width:" + width + " height:" + height);
            System.out.println("imageType:" + imageType);
            System.out.println("size:"+(offset + hh * scansize + dd));
            // rgb的陣列,儲存畫素,用一維陣列表示二點陣圖像畫素陣列
            int[] rgbArray = new int[offset + hh * scansize + dd];// 偏移量+縱向開始座標*掃描間距+橫向開始座標
            //這裡大家都感覺很奇怪為什麼會是這樣一個演算法呢?為什麼不知道用width*height就夠用了,這裡作者也搞不懂,你只要預設記住了這個規則,
            //然後取點的時候按這個規則去取就可以了
            // newArray 儲存處理後的畫素
            int[] newArray = new int[offset + hh * scansize + dd];// 偏移量+縱向開始座標*掃描間距+橫向開始座標
            /**
             * getRGB public int[] getRGB(int startX, int startY, int w, int h,
             * int[] rgbArray, int offset, int scansize)從影象資料的某一部分返回預設 RGB 顏色模型
             * (TYPE_INT_ARGB) 和預設 sRGB 顏色空間中整數畫素陣列。如果該預設模型與該影象的 ColorModel
             * 不匹配,則發生顏色轉換。在使用此方法所返回的資料中,每個顏色分量只有 8 位精度。通過影象中指定的座標 (x, y),ARGB
             * 畫素可以按如下方式訪問:
             * 
             * pixel = rgbArray[offset + (y-startY)*scansize + (x-startX)];
             * 如果該區域不在邊界內部,則丟擲 ArrayOutOfBoundsException。但是,不保證進行顯式的邊界檢查。
             * 
             * 
             * 引數:
             *  startX - 起始 X 座標 
             *  startY - 起始 Y 座標 
             *  w - 區域的寬度 
             *  h - 區域的高度
             * rgbArray - 如果不為 null,則在此寫入 rgb 畫素 
             * offset - rgbArray 中的偏移量
             * scansize - rgbArray 的掃描行間距 
             * 返回: RGB 畫素陣列。
             */
            img.getRGB(startX, startY, width, height, rgbArray, offset,
                    scansize); // 把畫素存到固定的數組裡面去
            int count=0;
            for(int i : rgbArray){
                System.out.println(i);
                if(i!=0){
                    count=count+1;
                }
            }
            System.out.println(count);
            int rgb = rgbArray[offset + (y0 - startY) * scansize
                    + (x0 - startX)]; // 位於圖片正中央的rgb畫素點
            Color c = new Color(rgb);
            System.out.println("中間畫素點的rgb:"+c);
            for (int i = 0; i < height - startY; i++) {//遍歷每一行
                for (int j = 0; j < width - startX; j++) {//遍歷每一列
                    c = new Color(rgbArray[offset+i * scansize + j]);
                    switch (type) {
                    case 1://紅色灰度圖片
                        newArray[i*dd + j] = new Color(c.getRed(), 0, 0).getRGB();
                        break;
                    case 2://綠色灰度圖片
                         newArray[i*dd + j] = new Color(0, c.getGreen(), 0).getRGB(); 
                        break;
                    case 3://藍色灰度圖片
                        newArray[i * dd + j] = new Color(0, 0, c.getBlue()).getRGB();
                        break;
 
                    default:
                        break;
                    }
 
                    
                    
                }
            }
            // 新建一個影象
            File out = new File(newFilePath);
            if (!out.exists())
                out.createNewFile();
            output = new FileOutputStream(out);
            BufferedImage imgOut = new BufferedImage(width, height,
                    BufferedImage.TYPE_3BYTE_BGR);
            imgOut.setRGB(startX, startY, width, height, newArray, offset,
                    scansize);
            ImageIO.write(imgOut, "jpg", output);
        } catch (IOException e) {
            // TODO 自動生成的 catch 塊
            e.printStackTrace();
        }
    }
}

本文轉自於:https://blog.csdn.net/hayre/article/details/50610187

此篇部落格,對我的幫助很大,在此非常感謝原創作者!