我需要创建合成人像马赛克(即由其他人像制成的人像)。请参阅下面的参考。
另一个很好的参考是AndreaMosaic。
http://www.andreaplanet.com/andreamosaic/samples/
或此youtube教程(跳到5分钟标记)
https://www.youtube.com/watch?v=9cy2gVm_ztQ
寻找最佳的方法,然后生成一个可供下载的jpeg文件。
理想情况下,它想使用Node / Javascript进行此操作,但可以使用PHP或其他任何方式。
关于从哪里开始有什么建议吗?到处都有一些库,但是没有什么库完全适合我想要的工作。
最佳答案
伪造的马赛克很简单。好吧,我尝试了一个简单的乘法,看起来像ti作品。
创建覆盖输入图像大小的照片纹理图案
调制灰度照片图案和原始图像
简单的乘法就可以。
这两个步骤都可以合并为一个步骤...这里是简单的C ++代码:
// globals
const int txrs=41; // number of textures for mosaic
picture txr[txrs]; // mosaic textures
picture pic0,pic1; // input and output images
// init
pic0.load("MonaLisa.jpg");
int sz=32; // mosaic grid size
for (int i=0;i<txrs;i++) // load/resize/grayscale textures
{
txr[i].load(AnsiString().sprintf("textures\\%03i.jpg",i)); // load image
txr[i].resize_fit(sz,sz,0x00000000); // resize to tile size
txr[i].enhance_range();
txr[i].pixel_format(_pf_u); // convert to grayscale <0,765>
txr[i].pixel_format(_pf_rgba); // convert to grayscale RGBA
}
pic0.resize_fit((pic0.xs/sz)*sz,(pic0.ys/sz)*sz,0x00000000); // cut not full tile size part of pic1
// mosaic
int xx,yy,x,y,i,j,sz=txr[0].xs,a,b;
color c0,c1;
pic1=pic0; // copy source image to destination
// process all regions
for (y=0;y<pic1.ys;y+=sz)
for (x=0;x<pic1.xs;x+=sz)
{
// select random texture
i=Random(txrs);
// proces region
for (yy=0;yy<sz;yy++)
for (xx=0;xx<sz;xx++)
{
// grayscale texture and original color image pixels
c0=txr[i].p[yy][xx];
c1=pic1.p[y+yy][x+xx];
// mutiply them
for (j=0;j<3;j++)
{
a=BYTE(c0.db[j]);
b=BYTE(c1.db[j]);
a=(a*b)>>8;
c0.db[j]=a;
}
// store to destinatio image
pic1.p[y+yy][x+xx]=c0;
}
}
pic1.save("out.png");
我将自己的图片类用于图片,因此一些成员是:
xs,ys
是图像大小(以像素为单位)p[y][x].dd
是(x,y)
位置的像素,为32位整数类型clear(color)
用color
清除整个图像resize(xs,ys)
将图像调整为新分辨率bmp
是具有Canvas
访问权限的VCL封装的GDI位图pf
保留图像的实际像素格式:enum _pixel_format_enum
{
_pf_none=0, // undefined
_pf_rgba, // 32 bit RGBA
_pf_s, // 32 bit signed int
_pf_u, // 32 bit unsigned int
_pf_ss, // 2x16 bit signed int
_pf_uu, // 2x16 bit unsigned int
_pixel_format_enum_end
};
color
和像素的编码如下:union color
{
DWORD dd; WORD dw[2]; byte db[4];
int i; short int ii[2];
color(){}; color(color& a){ *this=a; }; ~color(){}; color* operator = (const color *a) { dd=a->dd; return this; }; /*color* operator = (const color &a) { ...copy... return this; };*/
};
乐队是:
enum{
_x=0, // dw
_y=1,
_b=0, // db
_g=1,
_r=2,
_a=3,
_v=0, // db
_s=1,
_h=2,
};
我使用的输入图像是这样的:
结果如下:
可能需要进行一些亮度调整才能匹配原始输入图像的属性。