我需要创建复合肖像马赛克(即用其他肖像制作的肖像)。见下面的参考文献。
另一个很好的参考是AndreaMosaic。 http://www.andreaplanet.com/andreamosaic/samples/
或者这个youtube教程(跳到5分钟标记) https://www.youtube.com/watch?v=9cy2gVm_ztQ
寻找最佳方法,然后生成一个可以下载的jpeg文件。 理想情况下,我希望使用Node / Javascript进行此操作,但可以使用PHP或其他任何方式。
有关从哪里开始的任何建议?这里和那里有一些库,但没有什么比我想做的更适合。
答案 0 :(得分:0)
伪造的马赛克很简单。好吧,我尝试了一个简单的乘法,看起来像是作品。
调制灰度照片图案和原始图像
简单的乘法就可以了。
这两个步骤可以合并为一个...这里简单的 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
VCL 已封装 GDI 具有Canvas
访问权限的位图
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,
};
我使用的输入图像是:
结果如下:
可能需要进行一些亮度调整以匹配原始输入图像属性。