我正在爲使用canvas和cordova的移動設備製作非常基本的圖像編輯器。 不幸的是,當涉及畫布時,javascript是記憶的豬,這會導致所有內容在移動設備上徹底崩潰。HTML畫布和內存使用
我使用cropperjs來處理裁剪。 (如果你有更好的,請讓我知道)。 Cropper只允許使用基本的64位數據URL來檢索圖像,這似乎是巨大的內存浪費。 一旦圖像被剪切,我需要重新顯示它再次裁剪。 一個好處是圖像被轉換爲黑色和白色的基礎上如何被裁剪。該部分工作得很好,但由於最終使用從畫布提取的dataURL,因此可能會再次使內存大小加倍。
頁面上的按鈕調用此函數。這是麻煩似乎開始的地方。
var originalImage = document.createElement('img');
var cropper;
function finish() {
var data=cropper.getCroppedCanvas().toDataURL();
originalImage.onload = function() {
cropper.replace(originalImage, false);
cropper.clear();
originalImage.onload=undefined;
};
originalImage.src=data;
}
我猜測最終的問題是,dataURL是如此之大,即使沒有在DOM它燒傷內存。這一小段代碼會導致chrome和firefox爲600kb照片添加大約700mb的RAM使用量。 有沒有更好的方法將修改後的圖像存儲在內存中?更小的東西?或者,有沒有辦法制作一個新的臨時文件並加載?或者我完全在錯誤的軌道上?
-Edits爲Blindman67的回答加載
const originalImage = document.createElement('canvas');
originalImage.ctx = originalImage.getContext("2d");
var cropper; //cropper is created and destroyed on image load, so I can't use const?
function finish() {
const cropped = cropper.getCroppedCanvas();
originalImage.width = cropped.width;
originalImage.height = cropped.height;
originalImage.ctx.drawImage(cropped,0,0);
cropper.clear();
cropper.replace(originalImage , false); //errors, TypeError: t.match is not a function, cropper.min.js (line 11, col 4244)
}
代碼從一個文件中的圖片上傳
$('#file').on('change', function (ev) {
var f = ev.target.files[0];
var fr = new FileReader();
fr.onload = function (ev2) {
console.dir(ev2);
if (cropper !== undefined) {
cropper.destroy();
}
//Probably something wrong with this part
$('#img').on("load",function(){
originalImage.width = this.width;
originalImage.height = this.height;
originalImage.ctx.drawImage(document.getElementById("img"),0,0);
}).attr('src', ev2.target.result);
//^^^^^
//obvious I've been at this awhile, efficiency went down the tubes \/
var image = document.getElementById("img");
var options = {
viewMode: 0,
dragMode: 'crop',
responsive: true,
autoCrop: false,
movable: false,
scalable: false,
zoomable: false,
zoomOnTouch: false,
zoomOnWheel: false,
ready: cropReady
};
cropper = new Cropper(image, options);
};
fr.readAsDataURL(f);
});
頁面本身基本上是
<div >
<img id="img" style="max-width: 100%; max-height: 100%"/>
</div>
- 編輯 它看起來像使用畫布而不是imgs效果不錯。
HTML:
<div class="span-filler">
<img id="img" style="max-width: 100%; max-height: 650px"/>
<canvas id="originalImg" style="display:none;max-width: 100%;max-height: 100%;">Please use Chrome or Firefox
</canvas>
</div>
腳本
var cropper;
var gBrightness = 0;
var orgImg = document.getElementById("originalImg");
function finish() {
cropper.replace(orgImg, true); //doesn't need to data URL oddly
var data = cropper.getCroppedCanvas();
orgImg.width = data.width;
orgImg.height = data.height;
orgImg.getContext("2d").drawImage(data, 0, 0);
cropper.replace(orgImg.toDataURL("Image/jpeg"), false); //does need it
cropper.clear();
}
$('#file').on('change', function (ev) {
var f = ev.target.files[0];
var fr = new FileReader();
fr.onload = function (ev2) {
console.dir(ev2);
if (cropper !== undefined) {
cropper.destroy();
}
$('#img').attr('src', ev2.target.result);
var image = document.getElementById("img");
var options = {
viewMode: 0,
dragMode: 'crop',
responsive: true,
autoCrop: false,
movable: false,
scalable: false,
zoomable: false,
zoomOnTouch: false,
zoomOnWheel: false,
ready: cropReady
};
cropper = new Cropper(image, options);
};
fr.readAsDataURL(f);
});
function cropReady() {
var data = cropper.getCroppedCanvas();
orgImg.width = data.width;
orgImg.height = data.height;
orgImg.getContext("2d").drawImage(data, 0, 0);
processImage(); //converts to black and white using web workers
}
//still looking for efficiencies here
function processImage(brightness) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
canvas.width = orgImg.width;
canvas.height = orgImg.height;
var imgPixels;
var imgPixelsSrc = orgImg.getContext("2d").getImageData(0, 0, orgImg.width, orgImg.height);
var myWorker = new Worker('js/image_editor/imageWorker.js');
myWorker.onmessage = function (e) {
imgPixels = e.data[0];
gBrightness = e.data[2];
ctx.putImageData(imgPixels, 0, 0);
cropper.replace(canvas.toDataURL("image/jpeg"), true);
};
if (brightness === undefined) {
myWorker.postMessage([imgPixelsSrc, true]);
} else {
myWorker.postMessage([imgPixelsSrc, false, brightness]);
}
}
此線有沒有意義:originalImage.onload =未定義;還有:cropper.replace。如果可能,請發佈代碼片段!使用簡單的畫布裁剪圖像的一部分。你可以收集圖像數據看看:https://www.w3schools.com/tags/canvas_getimagedata.asp –
當我搜索「簡單的畫布」時,我沒有發現任何明顯的東西。我現在正在使用它,但如果有更好的一個,我願意切換到另一個。 https://github.com/fengyuanchen/cropperjs。 'cropper.replace(originalImage,false);'將htmlimage作爲第一個參數,並更新顏色或全部作爲第二個參數,對於顏色只有true,對於重新加載爲false。由於理論上圖像尺寸已改變,因此需要重新加載。 –