日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java彩色的世界_JAVA真彩色转256色的实现

發(fā)布時間:2024/9/19 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java彩色的世界_JAVA真彩色转256色的实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

色彩轉(zhuǎn)換算法

實現(xiàn)真彩色到256色的轉(zhuǎn)換,關(guān)鍵就是如何從24位真彩色的顏色中選出256種顏色,使圖像失真較小。主要的算法有:

(1)取顏色高位算法,例如:分別取R高3位,G高2位,B高3位組成8字節(jié)獲取256種顏色。

(2)流行色算法。算法的基本思路是:對彩色圖像中所有色彩出現(xiàn)的次數(shù)進行統(tǒng)計分析,從而選取頻率最高的N(256)種顏色,為這N(256)種顏色建立調(diào)色板。算法特點:算法簡單容易實現(xiàn),變換效果好,但一些出現(xiàn)頻率較低,但對人眼視覺效果明顯的信息將丟失。

(3)八叉樹顏色量化算法。算法基本思路是:將圖像中使用的RGB顏色值分布到層狀的八叉樹中。八叉樹的深度可達9層,即根節(jié)點層加上分別表示8位的R、G、B值的每一位的8層節(jié)點。較低的節(jié)點層對應于較不重要的RGB值的位(右邊的位),因此,為了提高效率和節(jié)省內(nèi)存,可以去掉最低部的2 ~ 3層,這樣不會對結(jié)果有太大的影響。葉節(jié)點編碼存儲像素的個數(shù)和R、G、B顏色分量的值;而中間的節(jié)點組成了從最頂層到葉節(jié)點的路徑。這是一種高效的存儲方式,既可以存儲圖像中出現(xiàn)的顏色和其出現(xiàn)的次數(shù),也不會浪費內(nèi)存來存儲圖像中不出現(xiàn)的顏色。算法特點:效率高,效果好。

JAVA真彩色轉(zhuǎn)換算法實現(xiàn)

這里,我們用以下兩種方式實現(xiàn)色彩的轉(zhuǎn)換:

(1)直接使用JAVA畫圖功能實現(xiàn)

(2)使用流行色算法實現(xiàn)

(一)使用JAVA畫圖功能實現(xiàn)轉(zhuǎn)換的方法

這里我們用JAVA的圖像庫實現(xiàn)顏色的轉(zhuǎn)換,我們先看看直接使用JAVA畫圖功能實現(xiàn)轉(zhuǎn)換的代碼及實現(xiàn)效果。

實現(xiàn)的基本思路是

(1)創(chuàng)建TYPE_BYTE_INDEXED類型的BufferedImage圖像對象。

(2)獲取該對象的畫圖對象Graphics2D,將真彩色圖像繪制到該圖像上。

(3)對新建的對象進行輸出,就得到了256色圖像。

下面是實現(xiàn)代碼

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

public class ColorTrueTo256 {

public static BufferedImage trueTo256(BufferedImage imgSrc) {

int width = imgSrc.getWidth();

int height = imgSrc.getHeight();

BufferedImage imgDst = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);

Graphics2D g2d = imgDst.createGraphics();

g2d.drawImage(imgSrc, 0, 0, width, height, null);

g2d.dispose();

return imgDst;

}

public static void main(String[] argv) throws IOException {

BufferedImage imgSrc = ImageIO.read(new File("landscape.jpg"));

BufferedImage imgDst = trueTo256(imgSrc);

ImageIO.write(imgDst, "gif", new File("landscape-1-256.gif"));

}

}

我們對以下圖像進行處理:

landscape.jpg

處理效果如下圖

landscape-1-256.gif

(二)使用流行色算法實現(xiàn)的方法及效果

用流行色算法實現(xiàn)轉(zhuǎn)換,大致的算法如下:

(1)準備一個長度為4096的數(shù)組,代表4096種顏色。對圖中的每一個像素,取R,G,B的最高四位,拼成一個12位的整數(shù),對應的數(shù)組元素加1。

(2)全部統(tǒng)計完后,就得到了這4096種顏色的使用頻率。這其中,可能有一些顏色一次也沒用到,即對應的數(shù)組元素為零。將這些為零的數(shù)組元素清除出去。

(3)將這剩余的數(shù)按從大到小的順序排列,這樣,前256種顏色就是用的最多的顏色,它們將作為調(diào)色板上的256種顏色。

(4)對于剩下的顏色并不是簡單的丟棄,而是用前面的256種顏色中的一種來代替,代替的原則是找有最小平方誤差的那個。

實現(xiàn)代碼如下:

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

public class TrueTo256 {

public static int colorTransfer(int rgb) {

int r = (rgb&0x0F00000)>>20;

int g = (rgb&0x000F000)>>12;

int b = (rgb&0x00000F0)>>4;

return (r<<8|g<<4|b);

}

public static int colorRevert(int rgb) {

int r = (rgb&0x0F00)<<12;

int g = (rgb&0x000F0)<<8;

int b = (rgb&0x00000F)<<4;

return (r|g|b);

}

private static int getDouble(int a, int b) {

int red = ((a&0x0F00)>>8) - ((b&0x0F00)>>8);

int grn = ((a&0x00F0)>>4) - ((b&0x00F0)>>4);

int blu = (a&0x000F) - (b&0x000F);

return red*red + blu*blu + grn*grn;

}

public static int getSimulatorColor(int rgb, int[] rgbs, int m) {

int r = 0;

int lest = getDouble(rgb, rgbs[r]);

for (int i=1; i < m; i++) {

int d2 = getDouble(rgb, rgbs[i]);

if (lest > d2) {

lest = d2;

r = i;

}

}

return rgbs[r];

}

public static void transferTo256(int[][] rgbs) {

int n = 4096;

int m = 256;

int[] colorV = new int[n];

int[] colorIndex = new int[n];

//初始化

for (int i=0; i < n; i++) {

colorV[i] = 0;

colorIndex[i] = i;

}

//顏色轉(zhuǎn)換

for (int x = 0; x < rgbs.length; x++) {

for (int y = 0; y < rgbs[x].length; y++) {

rgbs[x][y] = colorTransfer(rgbs[x][y]);

colorV[rgbs[x][y]]++;

}

}

//出現(xiàn)頻率排序

boolean exchange;

int r;

for (int i=0; i < n; i++) {

exchange = false;

for (int j=n-2; j>=i; j--) {

if (colorV[colorIndex[j+1]] > colorV[colorIndex[j]]) {

r = colorIndex[j];

colorIndex[j] = colorIndex[j+1];

colorIndex[j+1] = r;

exchange = true;

}

}

if (!exchange) break;

}

//顏色排序位置

for (int i=0; i < n; i++) {

colorV[colorIndex[i]] = i;

}

for (int x = 0; x < rgbs.length; x++) {

for (int y = 0; y < rgbs[x].length; y++) {

if (colorV[rgbs[x][y]] >= m) {

rgbs[x][y] = colorRevert(getSimulatorColor(rgbs[x][y], colorIndex, m));

} else {

rgbs[x][y] = colorRevert(rgbs[x][y]);

}

}

}

}

public static void transferToRed(int[][] rgbs) {

for (int x = 0; x < rgbs.length; x++) {

for (int y = 0; y < rgbs[x].length; y++) {

rgbs[x][y] = rgbs[x][y]&0x00FF0000;

}

}

}

public static void transferToGreen(int[][] rgbs) {

for (int x = 0; x < rgbs.length; x++) {

for (int y = 0; y < rgbs[x].length; y++) {

rgbs[x][y] = rgbs[x][y]&0x00FF00;

}

}

}

public static void transferToBlue(int[][] rgbs) {

for (int x = 0; x < rgbs.length; x++) {

for (int y = 0; y < rgbs[x].length; y++) {

rgbs[x][y] = rgbs[x][y]&0x00FF;

}

}

}

public static BufferedImage trueTo256(BufferedImage img) {

int[][] rgbs = new int[img.getWidth()][img.getHeight()];

BufferedImage cloneImg = new BufferedImage(img.getWidth(), img.getHeight(),

BufferedImage.TYPE_INT_RGB);

for (int x=0; x < rgbs.length; x++) {

for (int y=0; y < rgbs[x].length; y++) {

rgbs[x][y] = img.getRGB(x, y);

}

}

transferTo256(rgbs);

for (int x=0; x < rgbs.length; x++) {

for (int y=0; y < rgbs[x].length; y++) {

cloneImg.setRGB(x, y, rgbs[x][y]);

}

}

return cloneImg;

}

public static void main(String[] argv) throws IOException {

BufferedImage imgSrc = ImageIO.read(new File("landscape.jpg"));

BufferedImage imgDst = trueTo256(imgSrc);

ImageIO.write(imgDst, "gif", new File("landscape-2-256.gif"));

}

}

用該算法對上面的圖片進行處理,實現(xiàn)效果如下:

landscape-2-256.gif

總結(jié)

以上是生活随笔為你收集整理的java彩色的世界_JAVA真彩色转256色的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。