Javascript 基于最近邻算法的画布图像缩放
我正在使用最近邻算法在画布上缩放图像。但是,当我将缩放栏移得更高时,图像中有一条白线,可以创建一个方形阵列 原始图像 在我移动比例尺之后 缩放是可行的,但问题只是白线。 对于我将在底部提供的源代码 1.htmlJavascript 基于最近邻算法的画布图像缩放,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
<!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