[gdip] 多张图片拼接出一副马赛克海报

Mr_MAO 11小时前 60

sshot-1.jpg

实现这种需求,必须解决两个核心问题: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();


最新回复 (1)
  • 光庆 9小时前
    0 2

返回