图像处理之颜色梯度变化 (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
6017 1
使用OpenCV实现Halcon算法(2)形状匹配开源项目,shape_based_matching
|
数据采集 芯片
GWAS全基因组关联分析入门教程
GWAS全基因组关联分析入门教程
|
计算机视觉
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
1711 0
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
|
网络安全 Docker 容器
进入正在运行的Docker容器的4种方式
进入正在运行的Docker容器的4种方式
13948 1
|
存储 缓存 编解码
Web端短视频编辑器的设计与实现 - 像做PPT一样做视频
对于视频的生产,一般的方案是交由专业机构去创作,但这将花费很多预算,如果我们能提供一个工具,基于知识的通用结构沉淀一些视频模版,让用户快速创作出视频知识内容岂不美哉?让想法再奔放些,如果我们能直接从知识库中抽取结构化的知识内容直接生成视频或是半成品视频,用户只需要稍作调整就能发布,这想想就很酷吧?是的,小蜜视频创作工具我就是想做这样一件事情。本篇分享来自阿里巴巴前端工程师李志成(敦固)在第十六届D2前端技术论坛的分享。
4070 0
Web端短视频编辑器的设计与实现 - 像做PPT一样做视频
|
3月前
|
缓存 项目管理 开发工具
UV实战教程,我啥要从Anaconda切换到uv来管理包?
本文对比Anaconda“手动挡”与uv“全自动挡”环境管理:uv以“项目即环境”为核心,支持`uv init`一键初始化、自动下载Python、智能依赖管理(`uv add/sync/run`)及PyCharm无缝对接,大幅提升Python开发效率与协作体验。(239字)
1232 11
UV实战教程,我啥要从Anaconda切换到uv来管理包?
|
机器学习/深度学习 JavaScript PyTorch
9个主流GAN损失函数的数学原理和Pytorch代码实现:从经典模型到现代变体
生成对抗网络(GAN)的训练效果高度依赖于损失函数的选择。本文介绍了经典GAN损失函数理论,并用PyTorch实现多种变体,包括原始GAN、LS-GAN、WGAN及WGAN-GP等。通过分析其原理与优劣,如LS-GAN提升训练稳定性、WGAN-GP改善图像质量,展示了不同场景下损失函数的设计思路。代码实现覆盖生成器与判别器的核心逻辑,为实际应用提供了重要参考。未来可探索组合优化与自适应设计以提升性能。
1206 7
9个主流GAN损失函数的数学原理和Pytorch代码实现:从经典模型到现代变体
|
Docker 容器
设置docker开机自启动,并设置容器自动重启
设置docker开机自启动,并设置容器自动重启
1783 0
|
编译器 Shell API
Python与C的联姻:探索Python的可移植性与C的底层力量
Python与C的联姻:探索Python的可移植性与C的底层力量
523 1