图像处理之颜色梯度变化 (Color Gradient)

简介: 图像处理之颜色梯度变化 (Color Gradient)

有过UI设计经验的一定对2D图形渲染中的Color Gradient 或多或少有些接触,很多编程


语言也提供了Gradient的接口,但是想知道它是怎么实现的嘛?



本文介绍三种简单的颜色梯度变化算法,就可以很容易实现常见的梯度变化算法


三种都要求提供两个参数即起始颜色RGB值, 最终颜色RGB的值。



垂直梯度颜色变化,效果如下:

0_1322353157O172.png



水平梯度颜色变化,效果如下:


0_1322353179JbbD.png


水平与垂直两个方向叠加梯度变化效果如下:

0_1322353186ulsG.png


算法代码及其解释



计算起始颜色和终点颜色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) {
    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 gradient color value for 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);
        
        rgbData[index] = ((a & 0xff) << 24) |
                ((r & 0xff) << 16)  |
                ((g & 0xff) << 8)   |
                ((b & 0xff));
        index++;
      }
    }
  }
  
  private void generateHVGradientImage(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;
    float size = (float)Math.pow(255.0d, 2.0);
    for(int row=0; row<256; row++) {
      for(int col=0; col<256; col++) {
        // set random color value for each pixel
        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);
        
        rgbData[index] = ((a & 0xff) << 24) |
                ((r & 0xff) << 16)  |
                ((g & 0xff) << 8)   |
                ((b & 0xff));
        index++;
      }
    }
  }
  
  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);
  }
 
}
相关文章
|
人工智能 算法 自动驾驶
使用OpenCV实现Halcon算法(2)形状匹配开源项目,shape_based_matching
使用OpenCV实现Halcon算法(2)形状匹配开源项目,shape_based_matching
5579 1
使用OpenCV实现Halcon算法(2)形状匹配开源项目,shape_based_matching
|
数据采集 芯片
GWAS全基因组关联分析入门教程
GWAS全基因组关联分析入门教程
|
算法 C++
OpenCV-白平衡(完美反射算法)
OpenCV-白平衡(完美反射算法)
955 0
|
计算机视觉
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
1574 0
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
|
网络安全 Docker 容器
进入正在运行的Docker容器的4种方式
进入正在运行的Docker容器的4种方式
13500 1
|
人工智能 数据可视化 API
自学记录鸿蒙API 13:Calendar Kit日历功能从学习到实践
本文介绍了使用HarmonyOS的Calendar Kit开发日程管理应用的过程。通过API 13版本,不仅实现了创建、查询、更新和删除日程等基础功能,还深入探索了权限请求、日历配置、事件添加及查询筛选等功能。实战项目中,开发了一个智能日程管理工具,具备可视化管理、模糊查询和智能提醒等特性。最终,作者总结了模块化开发的优势,并展望了未来加入语音助手和AI推荐功能的计划。
1089 1
|
缓存 Python
深入理解Python中的装饰器
本文旨在通过具体实例和详细解释,帮助读者深入理解Python中装饰器的工作原理及其在实际开发中的应用。我们将从装饰器的基本概念开始,逐步深入到其高级用法,包括自定义装饰器、带参数的装饰器以及类装饰器等。通过本文的学习,读者将能够掌握装饰器的核心思想,提高代码的可读性和可维护性。
|
编译器 Shell API
Python与C的联姻:探索Python的可移植性与C的底层力量
Python与C的联姻:探索Python的可移植性与C的底层力量
395 1
|
设计模式 安全 C#
单例模式详解
单例模式是一种常用的创建型设计模式,确保某个类只有一个实例,并提供一个全局访问点。本文详细介绍了单例模式的定义、特点、适用场景、优缺点及实现代码(C++ 和 C#),并探讨了线程安全的实现细节和与依赖注入的结合使用。
|
Docker 容器
设置docker开机自启动,并设置容器自动重启
设置docker开机自启动,并设置容器自动重启
1566 0