天天看點

圖像處理------顔色梯度變化 (Color Gradient)

有過ui設計經驗的一定對2d圖形渲染中的color gradient 或多或少有些接觸,很多程式設計

語言也提供了gradient的接口,但是想知道它是怎麼實作的嘛?

本文介紹三種簡單的顔色梯度變化算法,就可以很容易實作常見的梯度變化算法

三種都要求提供兩個參數即起始顔色rgb值, 最終顔色rgb的值。

垂直梯度顔色變化,效果如下:

圖像處理------顔色梯度變化 (Color Gradient)

水準梯度顔色變化,效果如下:

圖像處理------顔色梯度變化 (Color Gradient)

水準與垂直兩個方向疊加梯度變化效果如下:

圖像處理------顔色梯度變化 (Color Gradient)

算法代碼及其解釋

計算起始顔色和終點顔色rgb之間內插補點代碼如下:

float rr = startcolor[0] - endcolor[0];

float gg = startcolor[1] - endcolor[1];

float bb = startcolor[2] - endcolor[2];

實作垂直梯度變化的代碼如下:

r = endcolor[0] + (int)(rr * ((float)row/255.0f) +0.5f);

g = endcolor[1] + (int)(gg * ((float)row/255.0f) +0.5f);

b = endcolor[2] + (int)(bb * ((float)row/255.0f) +0.5f);

實作水準梯度變化代碼如下:

// set gradient color valuefor each pixel

r = endcolor[0] + (int)(rr * ((float)col/255.0f) +0.5f);

g = endcolor[1] + (int)(gg * ((float)col/255.0f) + 0.5f);

b = endcolor[2] + (int)(bb * ((float)col/255.0f) +0.5f);

實作水準和垂直兩個方向上gradient疊加代碼如下:

r = endcolor[0] + (int)(rr * (((float)col * (float)row)/size) +0.5f);

g = endcolor[1] + (int)(gg * (((float)col * (float)row)/size) +0.5f);

b = endcolor[2] + (int)(bb * (((float)col * (float)row)/size) +0.5f);

程式對上面三種gradient方法分别放在三個不同的方法中,根據參數調用。

程式的完全java源代碼如下:

import java.awt.borderlayout;  

import java.awt.dimension;  

import java.awt.graphics;  

import java.awt.graphics2d;  

import java.awt.renderinghints;  

import java.awt.image.bufferedimage;  

import javax.swing.jcomponent;  

import javax.swing.jframe;  

public class colorgradientdemo extends jcomponent {  

    /** 

     *  

     */  

    private static final long serialversionuid = -4134440495899912869l;  

    private bufferedimage image = null;  

    protected void paintcomponent(graphics g) {  

        graphics2d g2 = (graphics2d)g;  

        g2.setrenderinghint(renderinghints.key_antialiasing, renderinghints.value_antialias_on);  

        g2.drawimage(getimage(4), 5, 5, image.getwidth(), image.getheight(), null);  

    }  

    public bufferedimage getimage(int type) {  

        if(image == null) {  

            image = new bufferedimage(256, 256, bufferedimage.type_int_argb);  

            int[] rgbdata = new int[256*256];  

            if(type == 1) {  

                generatevgradientimage(rgbdata);  

            } else if(type == 2) {  

                generatehgradientimage(rgbdata);  

            } else {  

                generatehvgradientimage(rgbdata);  

            }  

            setrgb(image, 0, 0, 256, 256, rgbdata);  

        }  

        return image;  

    private void generatevgradientimage(int[] rgbdata) {  

        int[] startcolor = getstartcolor();  

        int[] endcolor = getendcolor();  

        float rr = startcolor[0] - endcolor[0];  

        float gg = startcolor[1] - endcolor[1];  

        float bb = startcolor[2] - endcolor[2];  

        int a=255;  

        int r=0, g=0, b=0;  

        int index = 0;  

        for(int row=0; row<256; row++) {  

            for(int col=0; col<256; col++) {  

                // set random color value for each pixel  

                // set gradient color value for each pixel  

                r = endcolor[0] + (int)(rr * ((float)row/255.0f) + 0.5f);  

                g = endcolor[1] + (int)(gg * ((float)row/255.0f) + 0.5f);  

                b = endcolor[2] + (int)(bb * ((float)row/255.0f) + 0.5f);  

                rgbdata[index] = ((a & 0xff) << 24) |  

                                ((r & 0xff) << 16)  |  

                                ((g & 0xff) << 8)   |  

                                ((b & 0xff));  

                index++;  

    private void generatehgradientimage(int[] rgbdata) {  

                r = endcolor[0] + (int)(rr * ((float)col/255.0f) + 0.5f);  

                g = endcolor[1] + (int)(gg * ((float)col/255.0f) + 0.5f);  

                b = endcolor[2] + (int)(bb * ((float)col/255.0f) + 0.5f);  

    private void generatehvgradientimage(int[] rgbdata) {  

        float size = (float)math.pow(255.0d, 2.0);  

                r = endcolor[0] + (int)(rr * (((float)col * (float)row)/size) + 0.5f);  

                g = endcolor[1] + (int)(gg * (((float)col * (float)row)/size) + 0.5f);  

                b = endcolor[2] + (int)(bb * (((float)col * (float)row)/size) + 0.5f);  

    public int[] getstartcolor() {  

        return new int[]{246,53,138};  

    public int[] getendcolor() {  

        return new int[]{0,255,255};  

    public void setrgb( bufferedimage image, int x, int y, int width, int height, int[] pixels ) {  

        int type = image.gettype();  

        if ( type == bufferedimage.type_int_argb || type == bufferedimage.type_int_rgb )  

            image.getraster().setdataelements( x, y, width, height, pixels );  

        else  

            image.setrgb( x, y, width, height, pixels, 0, width );  

    public static void main(string[] args) {  

        jframe frame = new jframe("gradient color panel");  

        frame.setdefaultcloseoperation(jframe.exit_on_close);  

        frame.getcontentpane().setlayout(new borderlayout());  

        // display the window.  

        frame.getcontentpane().add(new colorgradientdemo(), borderlayout.center);  

        frame.setpreferredsize(new dimension(280,305));  

        frame.pack();  

        frame.setvisible(true);  

}