Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 基于最近邻算法的画布图像缩放_Javascript_Algorithm_Image Processing_Canvas_Scaling - Fatal编程技术网

Javascript 基于最近邻算法的画布图像缩放

Javascript 基于最近邻算法的画布图像缩放,javascript,algorithm,image-processing,canvas,scaling,Javascript,Algorithm,Image Processing,Canvas,Scaling,我正在使用最近邻算法在画布上缩放图像。但是,当我将缩放栏移得更高时,图像中有一条白线,可以创建一个方形阵列 原始图像 在我移动比例尺之后 缩放是可行的,但问题只是白线。 对于我将在底部提供的源代码 1.html <!DOCTYPE HTML> <html> <head> <title>Prototype PC</title> </head> <body> <canvas id='canva

我正在使用最近邻算法在画布上缩放图像。但是,当我将缩放栏移得更高时,图像中有一条白线,可以创建一个方形阵列

原始图像

在我移动比例尺之后

缩放是可行的,但问题只是白线。 对于我将在底部提供的源代码

1.html

 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Prototype PC</title>
 </head>
 <body>
 <canvas id='canvas1'></canvas>
 <hr>
 <button id='read'>READ IMAGE</button>
 <hr>
      Scale <input type='range' value='1' min='1' max='5' step='0.25' id='scale'>
      <br><button id='default2'>Default Scalling</button>
 <hr/>
 </body>
 <style>
 body{
      background : rgba(255,255,255,1);
 }
 </style>
 <script src='imagine.js'></script>
 <script>

 var canvas = document.getElementById('canvas1')
 var obj = new pc(canvas)
 obj.image2canvas("565043_553561101348179_1714194038_a.jpg")

 var tes = new Array()
 document.getElementById('read').addEventListener('click',function(){
    tes = obj.image2read()
 })

 document.getElementById('scale').addEventListener('change',function(){
    var scaleval = this.value
    var xpos = 0
    var ypos = 0
    var xnow = 0
    var ynow = 0
    var objW = obj.width
    var objH = obj.height

    tesbackup = new Array()
    for(var c=0; c<tes.length; c++){
        temp = new Array()
        for(var d=0; d<4; d++){
            temp.push(255)
        }
        tesbackup.push(temp)
    }
    //end of copy
    for(var i=0; i<tes.length; i++){
        xpos = obj.i2x(i)
        ypos = obj.i2y(i)
        xnow = Math.round(xpos) * scaleval)
        ynow = Math.round(ypos) * scaleval)
        if (xnow < objW && ynow < objH) {
            for (var j=0; j<scaleval; j++) {
                for (var k=0; k<scaleval; k++) {
                    var idxnow = obj.xy2i(xnow,ynow)
                    tesbackup[idxnow][0] = tes[i][0]
                    tesbackup[idxnow][1] = tes[i][1]
                    tesbackup[idxnow][2] = tes[i][2]
                }
              }
           }
        }
        obj.array2canvas(tesbackup)
    })
</script>

原型电脑

读取图像
规模
默认缩放
身体{ 背景:rgba(255255,1); } var canvas=document.getElementById('canvas1') var obj=新电脑(画布) obj.image2canvas(“565043_553561101348179_1714194038_a.jpg”) var tes=新数组() document.getElementById('read').addEventListener('click',function(){ tes=obj.image2read() }) document.getElementById('scale')。addEventListener('change',function(){ var scaleval=this.value var xpos=0 var ypos=0 var xnow=0 var ynow=0 var objW=obj.width var objH=obj高度 tesbackup=新阵列() 对于(var c=0;向外蜷缩像素) 最近的像素将导致某些缩放的像素比其他像素大

scaleval的值有问题。它的步长为0.25,当你计算每个缩放像素地址时(我猜你的代码有语法错误)
Math.round(xpos*scaleval)
但是你只使用分数大小(如2.75)而不是整数大小(如3.0)来绘制像素

每个像素的大小与y的大小相同。这样,当像素缩放不是整数值时,每缩放这么多像素,就会有一个像素变宽和变高

下面是对代码的修复,但由于您有许多语法错误和bug,我不得不猜测您的一些意图

xpos = obj.i2x(i)
ypos = obj.i2y(i)
xnow = Math.round(xpos * scaleval)
ynow = Math.round(ypos * scaleval)
// pixel width and height
var pw = Math.round((xpos + 1) * scaleval) - xnow;
var ph = Math.round((ypos + 1) * scaleval) - ynow;
if (xnow < objW && ynow < objH) {
    for (var y = 0; y < ph; y++) {
        for (var x  =0; x < pw; x++) {
            var idxnow = obj.xy2i(xnow + x, ynow + y)
            tesbackup[idxnow][0] = tes[i][0]
            tesbackup[idxnow][1] = tes[i][1]
            tesbackup[idxnow][2] = tes[i][2]
        }
      }
   }
}
xpos=obj.i2x(i)
ypos=对象i2y(i)
xnow=Math.round(xpos*scaleval)
ynow=数学圆(ypos*scaleval)
//像素宽度和高度
var pw=数学取整((xpos+1)*scaleval)-xnow;
var ph=数学圆整((ypos+1)*标度-ynow;
if(xnow
但您并不是在真正执行最近邻算法。为此,您需要迭代每个目标像素,找到最近的像素并使用其颜色。这样,您可以轻松地对缩放应用变换,但仍然可以获得每个像素,并且不会因舍入错误而跳过像素

近邻 对缩放旋转和平移图像使用最近邻查找的示例

var scaleFac = 2.3; // scale 1> zoom in 
var panX = 10;  // scaled image pan
var panY = 10; 
var ang = 1;
var w = ctx.canvas.width;  // source image
var h = ctx.canvas.height;
var wd = ctx1.canvas.width;  // destination image
var hd = ctx1.canvas.height;
// use 32bit ints as we are not interested in the channels
var src = ctx.getImageData(0, 0, w, h);
var data = new Uint32Array(src.data.buffer);// source
var dest = ctx1.createImageData(wd, hd);
var zoomData = new Uint32Array(dest.data.buffer);// destination
var xdx = Math.cos(ang) * scaleFac;  // xAxis vector x
var xdy = Math.sin(ang) * scaleFac;  // xAxis vector y
var ind = 0;
var xx,yy;
for(var y = 0; y < hd; y ++){
    for(var x = 0; x < wd; x ++){
        // transform point
        xx = (x * xdx - y * xdy + panX);
        yy = (x * xdy + y * xdx + panY);
        // is the lookup pixel in bounds
        if(xx >= 0 && xx < w && yy >= 0 && yy < h){                
             // use the nearest pixel to set the new pixel
             zoomData[ind++] = data[(xx | 0) + (yy | 0) * w]; // set the pixel
        }else{
             zoomData[ind++] = 0; // pixels outside bound are transparent
        }
    }
}

ctx1.putImageData(dest, 0, 0); // put the pixels onto the destination canvas


    
    
var scaleFac=2.3;//缩放1>放大
var panX=10;//缩放图像平移
var panY=10;
var ang=1;
var w=ctx.canvas.width;//源图像
var h=ctx.canvas.height;
var wd=ctx1.canvas.width;//目标图像
var hd=ctx1.canvas.height;
//使用32位整数,因为我们对通道不感兴趣
var src=ctx.getImageData(0,0,w,h);
var data=new uint32数组(src.data.buffer);//源
var dest=ctx1.createImageData(wd,hd);
var zoomData=new uint32数组(dest.data.buffer);//目的地
var xdx=Math.cos(ang)*scaleFac;//xAxis向量x
var xdy=Math.sin(ang)*scaleFac;//xAxis向量y
var-ind=0;
变量xx,yy;
对于(变量y=0;y=0&&xx=0&&yy
您能创建工作JSFIDLE代码段吗?
var scaleFac = 2.3; // scale 1> zoom in 
var panX = 10;  // scaled image pan
var panY = 10; 
var ang = 1;
var w = ctx.canvas.width;  // source image
var h = ctx.canvas.height;
var wd = ctx1.canvas.width;  // destination image
var hd = ctx1.canvas.height;
// use 32bit ints as we are not interested in the channels
var src = ctx.getImageData(0, 0, w, h);
var data = new Uint32Array(src.data.buffer);// source
var dest = ctx1.createImageData(wd, hd);
var zoomData = new Uint32Array(dest.data.buffer);// destination
var xdx = Math.cos(ang) * scaleFac;  // xAxis vector x
var xdy = Math.sin(ang) * scaleFac;  // xAxis vector y
var ind = 0;
var xx,yy;
for(var y = 0; y < hd; y ++){
    for(var x = 0; x < wd; x ++){
        // transform point
        xx = (x * xdx - y * xdy + panX);
        yy = (x * xdy + y * xdx + panY);
        // is the lookup pixel in bounds
        if(xx >= 0 && xx < w && yy >= 0 && yy < h){                
             // use the nearest pixel to set the new pixel
             zoomData[ind++] = data[(xx | 0) + (yy | 0) * w]; // set the pixel
        }else{
             zoomData[ind++] = 0; // pixels outside bound are transparent
        }
    }
}

ctx1.putImageData(dest, 0, 0); // put the pixels onto the destination canvas