Processing玩转国庆头像生成

2021-10-14 17:08:58 浏览数 (1)

国庆节了,抖音上各种国庆头像生成器,有的在 Web 端使用,有的是使用微信小程序进行制作,这事咱 Processing 也能做嘛。说撸就撸一个,简单粗暴。

昨晚没写完,中午接着写完了下,代码已经开源。

开源地址:https://github.com/xiaocai-laoniao/Processing100DaysSketch

代码在 Day_027 文件夹中,已经加了详细的注释,如果大家有不明白的,可以留言~

实现思路

封面图的获取

首先从网上找几个大家常用的国庆头像封面图,下载下来,保存到 data 文件夹中,这里依次命名为 header1.png ~ header7.png, 一共 7 张 png 图。

功能划分

头像和封面图合成显示

第一部分头像和封面图合成预览区域,这块使用PGraphics来解决,可以将之看成一个单独的图层,方便我们只将合成头像部分导出保存。

代码语言:javascript复制
// 头像图层,包含头像和头像的框图封面
PGraphics avatarLayer;

void draw() {
  background(200);

  // 头像图层的绘制部分
  avatarLayer.beginDraw();
  avatarLayer.pushMatrix();
  avatarLayer.background(200);
  if (avatarImage != null) {
    // 绘制头像
    avatarLayer.image(avatarImage, 0, 0);
  } else {
    // 如果没选图像,默认一个矩形填充
    avatarLayer.fill(100);
    avatarLayer.noStroke();
    avatarLayer.rect(0, 0, avatarSize, avatarSize);
  }
  // 获取当前选中的封面图数据
  PImage currentSelectedCoverImage = coverImages[currentSelectedCoverIndex];
  // 绘制头像封面
  avatarLayer.image(currentSelectedCoverImage, 0, 0);
  avatarLayer.popMatrix();
  avatarLayer.endDraw();

  ...
}

头像的选择

这里涉及到一个文件选择器的使用,API 为selectInput

函数的用法为selectInput(prompt, callback),第一个参数是提示语,第二个参数是一个回调函数名称,也就是选择结束后要执行的函数。看下方代码,我们的回调函数为fileSelected

代码语言:javascript复制
void keyPressed() {
  if (key == 'c' || key == 'C') {
    selectInput("选择头像文件(png/jpg/jpeg格式)", "fileSelected");
  } else if (key == 's' || key == 'S') {
    avatarLayer.save("NationalDayAvatar-"   frameCount   ".png");
    println("保存头像成功");
  }
}

void fileSelected(File selection) {
  if (selection == null) {
    println("[文件选择] 取消文件选择");
  } else {
    imageChoosedPath = selection.getAbsolutePath();
    println("[文件选择] 选择文件 "   imageChoosedPath);

    String[] paths = split(imageChoosedPath, "/");
    String fileName = paths[paths.length - 1];
    // 检测下文件后缀是否是png/jpg/jpeg等格式
    Boolean isValidImage = checkFileExtension(fileName);
    if (isValidImage) {
      // 加载读取头像文件
      avatarImage = loadImage(imageChoosedPath);
      // 进行resize
      avatarImage.resize(avatarSize, avatarSize);
    } else {
      println("[文件选择] 文件选择非 png/jpg/jpeg 格式");
    }
  }
}

封面图预览的切换选择

思路是将封面图封装起来,用isSelected标记是否选中,在绘制的时候加上红色边框。

代码语言:javascript复制
  // 绘制部分
  void display() {
    pushMatrix();
    
    // 选中的情况下,在图像后面画一个框
    if (this.isSelected) {
      stroke(255, 0, 0);
      strokeWeight(4);
      noFill();
      rect(this.x - 2, this.y - 2, coverSize   4, coverSize   4);
    }

    // 预览图显示
    image(coverImg, this.x, this.y);

    popMatrix();
  }

切换的话,需要检测鼠标按压时是否在某个封面预览图区域里面,如果在,则标记为选中,同时取消上一个选中的封面。

代码语言:javascript复制
void mousePressed() {
  // 检测鼠标按压区域,是否在某个模版预览区域
  for (int i = 0; i < covers.length; i  ) {
    Cover cover = covers[i];
    if (cover.isIn()) {
      covers[currentSelectedCoverIndex].isSelected = false;

      currentSelectedCoverIndex = i;
      cover.isSelected = true;

      break;
    }
  }
}

整个思路比较简单,目前不支持头像选择后的缩放、裁剪等,所以建议选择一个正常形的头像,防止加载resize之后发生变形。

最后

小菜祝大家国庆节快乐!

小菜与老鸟后期会不定期更新一些 Processing 绘制的代码思路分析,欢迎关注不迷路。

如果有收获,能一键三连么?

0 人点赞