Canvas.toDataURL() приводит к появлению черного цвета после перемещения содержимого из файла:/// в содержимое:// (xapk/obb) на Android Cordova
Я использую следующие плагины с Cordova 5.4.1:
- WhitelistPlugIn
- XAPKReader
Заголовок index.html включает в себя этот метатег CSP (пришлось увеличить URL-адреса Google TalkBack):
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline' 'unsafe-eval'
data: gap: content: cdvfile: ....google-URLS...;
img-src data: gap: file: content: cdvfile: ....google-URLS...;
style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval';
connect-src 'self' ....google-URLS..." />
Файл config.xml включает в себя:
<allow-navigation href="http://*/*" />
<access origin="*://*" />
<allow-intent href="content://*" />
<allow-intent href="content://*/*/*/*" />
Мой код, связанный с холстом, выглядит следующим образом и работает нормально, когда холст показывает изображения с URL-адресом file: /// *, но не с URL-адресами, подобными содержимому: /// *
html2canvas($("#layerA"), {onrendered:function(stageCanvas){
var stageCtx = stageCanvas.getContext('2d');
var tmpCanvas = document.createElement('canvas');
tmpCanvas.width = stageCanvas.width;
tmpCanvas.height = stageCanvas.height;
var tmpCtx = stageCanvas.getContext('2d');
var imgObj = new Image();
imgObj.onload = function(){
var destX = 0;
var destY = 0;
tmpCtx.drawImage(imgObj,
sourceX, sourceY, sourceWidth, sourceHeight,
0, 0, destWidth, destHeight);
var data = tmpCtx.getImageData(sourceX, sourceY, sourceWidth, sourceHeight);
stageCtx.clearRect(0, 0, stageCanvas.width, stageCanvas.height); //clear originalCanvas
stageCanvas.width = sourceWidth;
stageCanvas.height = sourceHeight;
tmpCtx.putImageData(data,0,0);
var datauri = null;
try {
datauri = stageCanvas.toDataURL('image/png');
} catch(err) {
alert(err);
}
// store the image and update UI
$('#fav-img-'+maxFavUsed.toString()).attr('src', datauri);
$("#fav-del-"+maxFavUsed.toString()).show();
$('#fav-big').attr('src', datauri);
if(typeof(Storage) !== "undefined") {
localStorage.setItem('fav-img-'+maxFavUsed.toString(), datauri);
}
showFav(maxFavUsed);
showUI();
//clear memory!!!
stageCtx.clearRect(0, 0, sourceWidth, sourceHeight);//clear originalCanvas
tmpCtx.clearRect(0, 0, sourceWidth, sourceHeight);//clear tmpCanvas
data = null;
datauri = null;
tmpCanvas = null;
stageCanvas = null;
imgObj = null;
};
try {
imgObj.src = tmpCanvas.toDataURL("image/png");
} catch(err) {
alert(err);
}
}, width:canvasW, height:canvasH } );
Приведенный выше код не выдает и не предупреждает, а создает пустые datauris, поэтому я предполагаю, что холст испорчен проблемой CORS. URL, начинающиеся с content: //, обслуживаются классом java ContentProvider, который поставляется с плагином XAPKReader.
1 ответ
Нашел способ самостоятельно. Похоже, что рисование холста на Android просто не заботится о мета-записи CSP и плагине белого списка. Поэтому перед вызовом приведенного выше кода я использую XMLHttpRequest()
а также .readAsDataURL()
заменить ссылки на изображения в URL-адресах фоновых изображений на их dataURI. Для этого я также должен был добавить свои полномочия ContentProvider content://FOO:*
к connect-src: часть метатега CSP. Затем холст правильно отображает.