2017-06-01 29 views
1

我試圖使用ctx.drawImage(image,sx,sy,sWidth,sHeight,dx,dy,dWidth,dHeight);用於從精靈圖像中提取圖像的API。但是我發現Canvas渲染了我不想要的相鄰圖像的邊緣。當從精靈圖像中提取圖像時,畫布不能正確地繪製邊緣

例如:

首先,我用一個800x400畫布繪製400x400的紅色矩形,紅色矩形後得出400x200綠色矩形,然後將數據保存到JPG文件。

enter image description here

然後我想提取的綠色矩形上繪製另一個畫布,所以我使用的語法如下:

ctx.drawImage(this, 400, 0, 400, 400, 0, 0, 400, 400); 

從理論上講,只有從綠色矩形的顏色數據畫布,但左邊有紅色。

JSBIN SAMPLE LINK

有誰知道爲什麼造成這個問題的原因?我誤解了API嗎?

在此先感謝。

+0

不知道api有沒有,但是你試過從1開始而不是0時使用drawImage? – stevenvanc

回答

3

這是因爲jpeg壓縮。 你可能沒有設置toDataURL('image/jpeg', quality)質量參數大於最大別的東西和默認1[編輯:實際上,由OP發現,默認爲.92]
通過這樣做,jpeg算法將採用更大的像素塊來完成其有損壓縮。你可以看到,在你的圖像上,兩個矩陣碰撞的地方,有一些反鋸齒僞像。

較低的壓縮,更大的這批文物將是:

// your original canvas 
 
var canvas = document.createElement('canvas'); 
 
var _ctx = canvas.getContext('2d'); 
 
canvas.width = 800; 
 
canvas.height = 400; 
 
_ctx.fillStyle = 'white'; 
 
_ctx.fillRect(0, 0, 800, 400); 
 
_ctx.fillStyle = 'red'; 
 
_ctx.fillRect(0, 0, 400, 400); 
 
_ctx.fillStyle = 'green'; 
 
_ctx.fillRect(400, 100, 400, 200); 
 

 

 
var img = document.createElement('img'); 
 
img.onload = function() { 
 
    // lets zoom a little bit 
 
    ctx.drawImage(this, 300, 0, 300, 300, 0, 0, 400, 400); 
 
} 
 
var ctx = document.getElementById('output').getContext('2d'); 
 

 
// since we do zoom the image, lets try to keep antialiasing as its minimum 
 
ctx.webkitImageSmoothingEnabled = 
 
    ctx.mozImageSmoothingEnabled = 
 
    ctx.msImageSmoothingEnabled = 
 
    ctx.imageSmoothingEnabled = false; 
 

 
range.oninput = function() { 
 
    img.src = canvas.toDataURL('image/jpeg', +this.value); 
 
} 
 
range.oninput();
<label>JPEG quality: <input type="range" id="range" min="0" max="1" step="0.01" value="1"></label><br> 
 
<canvas id="output" height="400"></canvas>

JPEG是偉大的照片,但有這樣的圖像,你應該堅持PNG,這將提供一個

var canvas = document.createElement('canvas'); 
 
var _ctx = canvas.getContext('2d'); 
 
canvas.width = 800; 
 
canvas.height = 400; 
 
_ctx.fillStyle = 'white'; 
 
_ctx.fillRect(0, 0, 800, 400); 
 
_ctx.fillStyle = 'red'; 
 
_ctx.fillRect(0, 0, 400, 400); 
 
_ctx.fillStyle = 'green'; 
 
_ctx.fillRect(400, 100, 400, 200); 
 

 

 
var img = document.createElement('img'); 
 
img.onload = function() { 
 
    // lets zoom even more 
 
    ctx.drawImage(this, 300, 0, 200, 200, 0, 0, 400, 400); 
 
} 
 
var ctx = document.getElementById('output').getContext('2d'); 
 
ctx.webkitImageSmoothingEnabled = 
 
    ctx.mozImageSmoothingEnabled = 
 
    ctx.msImageSmoothingEnabled = 
 
    ctx.imageSmoothingEnabled = false; 
 
img.src = canvas.toDataURL('image/png'); 
 

 
canvas.toBlob(function(b){console.log('jpg_size', b.size)}, 'image/jpeg', .1); 
 
canvas.toBlob(function(b){console.log('png_size', b.size)}, 'image/png');
<canvas id="output" height="400"></canvas>
:無損壓縮,並且將甚至此確切圖像上產生更小的圖像尺寸

+0

感謝您的詳細解釋。我很感激! – Sam

+1

順便說一句,我剛剛檢查了toDataURL的默認質量參數,我發現一篇文章說默認值是0.92。 https://stackoverflow.com/questions/33904144/whats-default-image-quality-in-todataurl – Sam

+0

@Sam,你是完全正確的,我忘了它,對我感到羞恥......更新。 – Kaiido