你好,欢迎进入江苏优软数字科技有限公司官网!

诚信、勤奋、创新、卓越

友好定价、专业客服支持、正版软件一站式服务提供

13262879759

工作日:9:00-22:00

sketch suffix 绘画与编程 - Processing 实现自动配色

发布时间:2025-02-14

浏览次数:0

在之前共享的文章中,图形是使用代码直接生成的,并且对绘画的讨论较少。这次,将介绍一个可以连接绘画和编程的示例。根据现有图片的颜色,插图自动匹配。

让我们先看看效果

(早期创建的线条草稿)

sketch suffix_sketch suffix_sketch suffix

(扫描计算机并进行简单的颜色调整)

sketch suffix_sketch suffix_sketch suffix

(从程序颜色匹配开始)

演示视频:

输出图片:

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

实施原则

例如,这里没有使用复杂的颜色匹配算法。只需在选定的图片上随机拾取颜色。该程序的源代码和相应的操作说明将在下面提供。即使您不知道编程,只要您具有一定程度的动手能力,也可以开始并体验它。

用户指南

准备:

1。下载,使用3.0版或更高版本

2。创建一个PSD源文件。填充包含线图和相应色块的图层

(PSD文件下载:)

该程序不是那么聪明,它不能自动直接为线路播放着色。一些工作仍需要手动完成。例如,将图像分层并保存使用独立图层的线图和着色层。

这些步骤也是CG绘画中常见的绘画过程,无法省略。

如果您使用的是扫描的手绘线图。然后,图片的背景自然是白色的,而不是透明的。目前,如果您选择在线手稿上方创建一个新图层以进行着色,则它将很容易覆盖并阻止线层。如果在下面选择,则由于线图层不透明,因此涂漆层将被阻止。

要解决此问题sketch suffix,请将衬套层设置为充值模式。

sketch suffix_sketch suffix_sketch suffix

主电影的效果有点像水彩画,颜色变得越来越深。线条图层上的零件越白,颜色越少,因此当与以下一层叠加时,不会产生影响,这将产生半透明的效果。黑暗的部分将被叠加并保留。

将行绘图层设置为充值层之后,然后将新创建的层放在下面,以直接绘制颜色。由于该程序只需要层的形状和轮廓,因此您可以在绘画时选择颜色来填充它。此外,应注意的是,屏幕上相同颜色的色块可以共享一层。例如,图片前的两种植物属于同一层

sketch suffix_sketch suffix_sketch suffix

(层)

sketch suffix_sketch suffix_sketch suffix

当所有对象都分层和彩色时,您可以开始下一步

sketch suffix_sketch suffix_sketch suffix

PS:除了场景中的线图,阴影和黑暗部分外,您还可以考虑使用单片堆栈。此模式在源文件中的图层中使用

3。所有具有“正常”层模式的层均为“美白”

sketch suffix_sketch suffix_sketch suffix

所有使用整体层的层都不需要白色。所谓的美白是消除图层本身的颜色趋势。在这里,使用快捷键CTRL + U将亮度调整为最大值。

PS:必须在这里白色,不仅要涂上颜色。此操作与程序的着色机制有关。只有将基本颜色调低为白色,才能以后模拟所有颜色。

PS2:熟悉脚本的朋友也只能在导出图像后批处理处理。无需一个一个人手动操作

4。层出口层

完成后,可以通过一个命令将该层分批导出。在菜单栏上选择“文件” - “脚本” - “导出层”

sketch suffix_sketch suffix_sketch suffix

将其设置为上面的,以导出具有相同大小和透明通道的PNG图像。示例中的图像均为417,高度为700。

sketch suffix_sketch suffix_sketch suffix

PS:出口前请清除一些不必要的隐藏层

5。将以下源代码复制到程序中并将其保存到特定路径

源代码:

import java.util.Date;
ArrayList mulPics = new ArrayList();
ArrayList normalPics = new ArrayList();
color myColors[];
int colorNum, mode; 
PImage pickPic;
void setup() {
  size(417, 700);
  mode = 1; // 0:randomPick 1;randomFromPic
  myColors = new color[0];
  File[] files = listFiles(sketchPath() + "/loadPic");
  for (int i = 0; i < files.length; i++) {
    File f = files[i];   
    String strArray[] = splitTokens(f.getName(), ".");
    String suffix = strArray[strArray.length-1];
    if (suffix.equals("png")||suffix.equals("jpg")||suffix.equals("jpeg")) {
      pickPic = loadImage("loadPic/" + f.getName());
    }
  }
  files = listFiles(sketchPath() + "/multiply");
  for (int i = 0; i < files.length; i++) {
    File f = files[i];   
    String strArray[] = splitTokens(f.getName(), ".");
    String suffix = strArray[strArray.length-1];
    if (suffix.equals("png")) {
      PImage temp = loadImage("multiply/" + f.getName());
      mulPics.add(temp);
    }
  }
  files = listFiles(sketchPath() + "/normal");
  for (int i = 0; i < files.length; i++) {
    File f = files[i];   
    String strArray[] = splitTokens(f.getName(), ".");
    String suffix = strArray[strArray.length-1];
    if (suffix.equals("png")) {
      PImage temp = loadImage("normal/" + f.getName());
      normalPics.add(temp);
      color tempColor = pickPic.get(int(random(0, pickPic.width)), 
        int(random(0, pickPic.height)));
      myColors = append(myColors, tempColor);
    }
  }
  colorNum = normalPics.size();
}
void draw() {
  background(255);
  imageMode(CENTER);
  blendMode(BLEND);
  for (int i = normalPics.size() - 1; i >= 0; i--) {
    tint(myColors[i]);
    PImage temp = normalPics.get(i);
    image(temp, width/2, height/2);
  }
  blendMode(MULTIPLY);
  for (int i = mulPics.size() - 1; i >= 0; i--) {
    tint(255);
    PImage temp = mulPics.get(i);
    image(temp, width/2, height/2);
  }
}
void keyPressed() {
  //  保存图片
  if (key == 's') {
    saveFrame(millis() + ".png");
  }
}
void mousePressed() {
  resetColor();
}
void mouseDragged() {
  resetColor();
}
void resetColor() {
  if (mode == 0) {
    myColors = new color[0];
    for (int i = 0; i < colorNum; i++) {
      color tempColor = color(random(255), random(255), random(255));
      myColors = append(myColors, tempColor);
    }
  }
  if (mode == 1) {
    myColors = new color[0];
    for (int i = 0; i < colorNum; i++) {
      color tempColor = pickPic.get(int(random(0, pickPic.width)), 
        int(random(0, pickPic.height)));
      myColors = append(myColors, tempColor);
    }
  }
}
File[] listFiles(String dir) {
  File file = new File(dir);
  if (file.isDirectory()) {
    File[] files = file.listFiles();
    return files;
  } else {
    return null;
  }
}

保存到特定位置后sketch suffix,将生成一个PDE文件。这是源程序。我们需要将以前在PS中导出的PNG材料复制到此源程序的目录。复制时,请勿更改导出图像的文件名。同时,如图所示,创建三个新文件夹。在该文件夹中,需要以正常模式显示的层(即,以前已经白色的层)。在文件夹中,需要显示主膜堆叠模式的存储层。在文件夹中,您可以将任何图像文件放在JPG,JPEG或PNG后缀中。之后,该程序将基于此图片。

sketch suffix_sketch suffix_sketch suffix

7。准备工作已经结束。最后,只需将程序中的大小(417,700)的两个参数分别修改为输出图像的宽度和高度即可。

sketch suffix_sketch suffix_sketch suffix

现在您可以一劳永逸地完成它,让程序帮助您完成着色工作

PS:尽量不要使用过高的定义图片,并尝试在加载之前减少图片的分辨率以适应屏幕尺寸。

8。任务完成〜只需单击或拖动鼠标切换颜色

当您看到令人满意的效果时,可以按S键保存。如果您认为上述步骤太麻烦了,也可以直接在文章末尾下载整个源文件。只要安装它,就可以直接打开并直接运行。将相应的图片材料拖到文件夹中,然后单击程序自动匹配颜色。

(其他实验)

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

详细的代码说明

以随机的方式获取颜色。自然,并非每个结果都令人满意,就像绘画一样,需要重复调​​试。此示例的重点不是提高效率本身,而是提出一个定量想法,使您可以探索各种音调组合。

接下来是技术分析,它将以最简单的代码开头

示例01

PImage outLine,pic1,pic2,pic3,pic4;
int seedNum;
void setup(){
  size(400,400);
  outLine = loadImage("0.png");
  pic1 = loadImage("1.png");
  pic2 = loadImage("2.png");
  pic3 = loadImage("3.png");
  pic4 = loadImage("4.png");
  seedNum = 0;
}
void draw(){
  randomSeed(seedNum); 
  background(random(255),random(255),random(255));
  blendMode(BLEND);
  imageMode(CENTER);
  tint(random(255),random(255),random(255)); 
  image(pic4,width/2,height/2);
  tint(random(255),random(255),random(255)); 
  image(pic3,width/2,height/2);
  tint(random(255),random(255),random(255)); 
  image(pic2,width/2,height/2);
  tint(random(255),random(255),random(255)); 
  image(pic1,width/2,height/2);
  blendMode(MULTIPLY);
  tint(255);
  image(outLine,width/2,height/2); 
}
void keyPressed(){
  if(key == '1'){
    seedNum++; 
  }
  if(key == '2'){
    seedNum--;
  }
  if(key == 's'){
    saveFrame(millis() + ".png"); 
  }
}

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

代码分析:

sketch suffix_sketch suffix_sketch suffix

示例02

ArrayList pics = new ArrayList();
int seedNum;
void setup() {
  size(400, 400);
  for (int i = 0; i <=4; i++) {
    PImage temp;
    temp = loadImage(str(i)+".png");
    pics.add(temp);
  }
  seedNum = 0;
}
void draw() {
  randomSeed(seedNum); 
  background(random(255), random(255), random(255));
  imageMode(CENTER);
  blendMode(BLEND);
  for (int i = 4; i >= 0; i--) {
    if (i != 4) {
      blendMode(ADD);
    }
    tint(random(255), random(255), random(255), 190);
    if (i == 0) {
      blendMode(MULTIPLY);
      tint(255);
    }
    PImage temp = pics.get(i);
    image(temp, width/2, height/2);
  }
}
void keyPressed() {
  if (key == '1') {
    seedNum++;
  }
  if (key == '2') {
    seedNum--;
  }
  if (key == '3') {
    saveFrame(millis() + ".png");
  }
}

跑步效果:

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

sketch suffix_sketch suffix_sketch suffix

代码分析:

sketch suffix_sketch suffix_sketch suffix

结尾

通过以上两个基本示例,在查看起点示例时并不难理解。更方便地读取图像文件只是更多语句。将来,随着您掌握的代码知识变得越来越丰富,您可以通过更好的想法来改进它。例如,创建自己的特殊着色板,完善各种着色规则,并扩展层次结构关系。

我一直认为绘画本身是一个连续的调试过程。为了学习这项技能,我们进行了很多练习,以掌握一组图形语言,以表达我们的想法更好,更快。

但是,您必须知道如何在创建图形之前绘制吗?我不这么认为。有时,我们可以要求该程序帮助我们“拿起笔”并完成这些调试工作。上面的示例是关于调试颜色,允许程序随机组合。目前,人们只需要担任法官并放映符合其美学口味的计划。

当然,此方法有局限性。由于图像材料是位图,因此无法更改对象的形状,并且很难准确控制它。除非您知道编程,否则这可能会破坏局限性并以更具参数化的方式描述这些形状,从而使树木可以生长,花朵和叶子可以飞行。

我相信,通过形状和颜色的结合,可以包括所有情况,并且所有内容都可以通过代码进行模拟。

下载地址

样本收集()

如有侵权请联系删除!

13262879759

微信二维码