
实现这种需求,必须解决两个核心问题:1、找到一个bitmap的平均颜色;2、判断两个颜色是否相近。
解决问题1:本例使用自定义的getAverageColor()函数,根据图像学中计算平均色的一种算法来实现。
(当然不懂写算法,可以将一个bitmap大小调整为1px,这个1px的颜色也就是平均色)
解决问题2:需要用到color库中的 color.distance(color1,color2) 函数,来求两个颜色color1和color2之间的“距离”,距离越小,颜色越接近。
以下是演示代码,写的不好,抛砖引玉吧~
import win.ui;
var winform = win.form(text="用gdip拼接马赛克大图";right=1207;bottom=491;clipch=1)
winform.add(
button={cls="button";text="建立图像数据库";left=24;top=16;right=216;bottom=56;dl=1;dt=1;z=1};
button2={cls="button";text="打开一张底图";left=232;top=16;right=424;bottom=56;dl=1;dt=1;z=5};
plus={cls="plus";left=24;top=72;right=600;bottom=460;db=1;dl=1;dt=1;edge=1;repeat="scale";z=2};
plus2={cls="plus";left=608;top=72;right=1184;bottom=459;db=1;dl=1;dr=1;dt=1;edge=1;repeat="scale";z=3};
progress={cls="progress";left=448;top=32;right=1184;bottom=48;dl=1;dr=1;dt=1;edge=1;max=100;min=0;z=4};
static={cls="static";text="Static";left=26;top=466;right=1186;bottom=490;db=1;dl=1;dr=1;transparent=1;z=6}
)
import fsys.dlg.dir;
import fsys.dlg;
import color;
getAverageColor = function(bmp,w,h){
var bmp2 = gdip.bitmap(w, h)
var g2 = bmp2.getGraphics()
g2.drawImageRect(bmp,0,0,bmp2.width,bmp2.height)
//读内存像素
var new_a,total_r,total_g,total_b = 0,0,0,0;
var bmpdata = bmp2.lockData32()
for(h=1; bmpdata.Height){
for(w=1; bmpdata.Width){
var curColor = bmpdata.bits.rows[h].pixels[w]
//rgb分量
var b = curColor & 0xff ;
var g = (curColor & 0xff00) >> 8
var r = (curColor & 0xff0000) >> 16
var a = (curColor & 0xff000000) >> 24
new_a := a;
total_r += r;
total_g += g;
total_b += b;
}
}
bmp2.unlockData(bmpdata);
var new_r = total_r/(bmp2.width*bmp2.height)
var new_g = total_g/(bmp2.width*bmp2.height)
var new_b = total_b/(bmp2.width*bmp2.height)
return new_b + (new_g << 8) + (new_r << 16) + (new_a << 24);
}
var imagestabs = {} //存放【颜色→图片路径】的数据库
winform.button.oncommand = function(id,event){
var folder = fsys.dlg.dir()
if(folder){
winform.button.disabledText = {"✶";"✸";"✹";"✺";"✹";"✷"; text="正在处理..."}
table.clear(imagestabs); //清空表
fsys.enum( folder, "*.jpg",
function(dir,filename,fullpath){
if(filename){
var bmp = gdip.bitmap(fullpath)
var averageColor = getAverageColor(bmp,100,100) //获取图像的平均色
var isExit = false
if(#imagestabs>1){
for(i=1;#imagestabs){
if(imagestabs[i][1]==averageColor) isExit = true
}
}
if(isExit==false) table.push(imagestabs, {averageColor, fullpath})
winform.static.text = fullpath;
}
win.peekPumpMessage(1)
} , true
);
var imgCount = #imagestabs
winform.static.text = "该文件夹中" ++ imgCount ++ "张图片已经编入马赛克数据库"
winform.button.disabledText = null;
winform.button2.disabled = false
}
}
winform.button2.oncommand = function(id,event){
var imgpath = fsys.dlg.open("图片文件|*.jpg")
if(imgpath){
//在左侧plus显示原图
winform.plus.background = imgpath
winform.plus2.background = null
winform.button2.disabledText = {"✶";"✸";"✹";"✺";"✹";"✷"; text="正在处理..."}
var bmp = gdip.bitmap(imgpath);
var g = bmp.getGraphics()
var rows,cols = 40, 40; //(电脑配置高的话,越大越好)
winform.progress.min = 0;
winform.progress.max = rows * cols;
winform.progress.pos = 0;
winform.progress.step = 1;
winform.progress.hide = false;
var x,y;
var w = bmp.width / rows //每个方块的宽度
var h = bmp.height/ cols //每个方块的高度
var w2 = w>100?100:w;
var h2 = h>100?100:h;
for(i=1;rows){
for(j=1;cols){
x, y = (i-1)*w, (j-1)*h;
var bmp2 = bmp.clone(x,y,w,h);
var averageColor = getAverageColor(bmp2,w2,h2);
table.sort(imagestabs,function(next){
var d1 = color.distance(averageColor,owner[1]);
var d2 = color.distance(averageColor,next[1]);
return d1 < d2;
});
bmp2 = gdip.bitmap( imagestabs[1][2] )
g.drawImageRect(bmp2,x,y,w,h)
winform.progress.stepIt()
win.peekPumpMessage(1);
}
}
winform.button2.disabledText = null;
winform.progress.hide = true;
//在右侧plus显示马赛克图
winform.plus2.background = bmp
}
}
winform.progress.hide = true;
winform.button2.disabled = true
winform.show();
win.loopMessage();