我想在Processing中构建一种图像变形工具。类似于你在这个链接中看到的:
https://giphy.com/gifs/painting-morph-oil-c8ygOpL64UDuw
我实现这一目标的第一步是构建一个二维像素网格。像素充满了色彩。填充颜色是通过使用get((从图像(PImage img1;(中读取颜色来创建的;作用这就是我用像素重新创建图像的方式。在第二步中,我想我会使用lerp((;函数为各个像素提供第二张图像的颜色(PImage img2;(-我认为这会创建所需的变形效果。但我错了!整个过程是有效的,但效果只是在两张图像之间发生了淡入。没有变形。在这种变形效果下,像素究竟会发生什么?如何在Processing中重新创建它?
float pixel;
float pixelsize;
PImage img1;
PImage img2;
float counter;
void setup() {
size(1080, 1080);
pixel = 100;
pixelsize = width/pixel;
noStroke();
img1 = loadImage("0.jpg");
img2 = loadImage("1.jpg");
counter = 0;
}
void draw() {
background(255);
for (int y = 0; y < pixel; y++) {
for (int x = 0; x < pixel; x++) {
color c1 = img1.get(int(pixelsize*x), int(pixelsize*y));
color c2 = img2.get(int(pixelsize*x), int(pixelsize*y));
color from = c1;
color to = c2;
color interA = lerpColor(from, to, counter);
pushMatrix();
translate(pixelsize*x, pixelsize*y);
fill(interA);
rect(0, 0, pixelsize, pixelsize);
popMatrix();
}
}
counter= counter + 0.01;
}
事实上,这不是一项直接的任务。
你的方法是一个不错的开始:它将导致两个图像之间的良好交叉。
裸get()
在CPU上的成本可能很高。但是,您可以使用pixels[]
:
PImage img1;
PImage img2;
// transition image
PImage imgT;
void setup() {
size(1080, 1080);
img1 = loadImage("0.jpg");
img2 = loadImage("1.jpg");
// copy the 1st image (copies width/height as well)
imgT = img1.get();
}
void draw() {
background(255);
// map transition amount to mouse X position
float t = map(mouseX, 0, width, 0.0, 1.0);
// make all pixels readable
imgT.loadPixels();
// lerp each pixel
for(int i = 0 ; i < imgT.pixels.length; i++){
imgT.pixels[i] = lerpColor(img1.pixels[i], img2.pixels[i], t);
}
// update all pixels in one go
imgT.updatePixels();
// display result
image(imgT, 0, 0);
}
实现完全变形图像并非易事。我可以重新修复两个选项来使用现有的算法,但这些选项对初学者也不友好:
- ImageMagick实现了shepards失真,并且有一个与ImageMagick接口的java库:im4java。请注意,您需要下载预编译的java库,并将.jar文件放在草图上,处理输出可能需要时间:可能不适用于实时(但是,应该可以将单个帧保存到磁盘上,并将其组装为gif/movie/等(
- 使用OpenCV:有一个OpenCV Face Morph教程,源代码为c++或Python,还有一个Processing OpenCV库。这将是一个将c++/Python OpenCV调用移植到Java OpenCV API的问题