[英]Transparent HTML5 canvas todataurl only rendering transparent background on mobile devices
編輯,請參閱問題結尾。
在我的應用程序中,我有兩個canvas元素。 一個顯示分層透明的png,另一個從文件輸入中獲取圖像並對其進行遮罩。 所選圖像在未被遮蓋的地方是透明的。 然后將此圖像轉換為dataUrl,進行轉換以適合第一個畫布,並添加為第一個畫布的頂層。
一切都能在桌面瀏覽器上正常運行:Chrome OSX,Safari OSX。 我只在加載時添加它,所以我確保不會發生競爭情況。
在Android Chrome和Safari iOS上,轉換為dataURL的畫布呈現為透明。 如果我將非透明圖像添加到第二個畫布,則渲染的圖像甚至將在移動設備上顯示。
為了檢查,我在身體上添加了所謂的透明畫布。 它在桌面上正確顯示,但在移動瀏覽器上透明。 這里是簡化的JS。 為了方便起見,我使用fabric.js,但是沒有lib的問題是相同的。 我什至一次添加了背景色。 然后將僅顯示顏色。 有什么想法為什么在移動瀏覽器中的todataurl只呈現透明像素?
<body>
<canvas id="canv"></canvas>
<script src="fabric.js"></script>
<script>
// main canvas
var c = new fabric.Canvas('canv');
c.setWidth(200);
c.setHeight(200);
var i = document.createElement('img');
i.src = 'dummy.jpg';
// i.src = 'dummy1.png';
i.onload = function(e) {
//document.body.appendChild(i);
scale = 1; // resizes the image
var ci = new fabric.Image(i);
ci.set({
left: 0,
top: 0,
scaleX: scale,
scaleY: scale,
originX: 'left',
originY: 'top'
}).setCoords();
// temporary canvas, will be converted to dataurl, contains transformed image
var tmpCanvas = new fabric.Canvas();
tmpCanvas.setWidth(100);
tmpCanvas.setHeight(100);
ci.scaleToWidth(100);
tmpCanvas.add(ci);
tmpCanvas.renderAll();
// create image from temporary canvas
var customImage = new fabric.Image.fromURL(tmpCanvas.toDataURL({ format: 'png' }), function (cImg) {
// add it to original canvas
c.clear();
c.add(cImg);
c.renderAll();
data = c.toDataURL({ format: 'png' });
// resized image
var newc = new fabric.StaticCanvas().setWidth(300).setHeight(300);
var newImg = new fabric.Image.fromURL(data, function (c1Img) {
newc.add(c1Img);
newc.renderAll();
// append to body to check if canvas is rendered correctly
document.body.appendChild(newc.lowerCanvasEl);
});
});
}
</script>
編輯:我解決了問題,但找不到Java腳本方面的問題。
問題是我將一個臨時畫布復制到了另一個畫布上。 通過在png中找到非透明像素的邊界框來計算添加的畫布的比例和位置,該邊界框正是為此目的而生成的。 簡短地說是面具。
邊界框是在應用程序啟動時在另一個臨時畫布中計算的(基於此答案)。 盡管正確設置了蒙版及其畫布的所有大小,並且從未將畫布添加到DOM,但是在小屏幕上加載時,邊框的結果與全屏結果有所不同。 經過大量測試后,我發現台式機也是如此。
因為我已經在這個問題上花了很多時間,所以我決定嘗試在PHP中計算邊界並將其放入data屬性。 哪個很棒!
對於那些對PHP解決方案感興趣的人:
function get_bounding_box($imgPath) {
$img = imagecreatefrompng($imgPath);
$w = imagesx($img);
$h = imagesy($img);
$bounds = [
'left' => $w,
'right' => 0,
'top' => $h,
'bottom' => 0
];
// get alpha of every pixel, if it is not fully transparent, write it to bounds
for ($yPos = 0; $yPos < $h; $yPos++) {
for ($xPos = 0; $xPos < $w; $xPos++) {
// Check, ob Pixel nicht vollständig transparent ist
$rgb = imagecolorat($img, $xPos, $yPos);
if (imagecolorsforindex($img, $rgb)['alpha'] < 127) {
if ($xPos < $bounds['left']) {
$bounds['left'] = $xPos;
}
if ($xPos > $bounds['right']) {
$bounds['right'] = $xPos;
}
if ($yPos < $bounds['top']) {
$bounds['top'] = $yPos;
}
if ($yPos > $bounds['bottom']) {
$bounds['bottom'] = $yPos;
}
}
}
}
return $bounds;
}
問題是我將一個臨時畫布復制到了另一個畫布上。 通過在png中找到非透明像素的邊界框來計算添加的畫布的比例和位置,該邊界框正是為此目的而生成的。 簡短地說是面具。
邊界框是在應用程序啟動時在另一個臨時畫布中計算的(基於此答案)。 盡管正確設置了蒙版及其畫布的所有大小,並且從未將畫布添加到DOM,但是在小屏幕上加載時,邊框的結果與全屏結果有所不同。 經過大量測試后,我發現台式機也是如此。
因為我已經在這個問題上花了很多時間,所以我決定嘗試在PHP中計算邊界並將其放入data屬性。 哪個很棒!
對於那些對PHP解決方案感興趣的人:
function get_bounding_box($imgPath) {
$img = imagecreatefrompng($imgPath);
$w = imagesx($img);
$h = imagesy($img);
$bounds = [
'left' => $w,
'right' => 0,
'top' => $h,
'bottom' => 0
];
// get alpha of every pixel, if it is not fully transparent, write it to bounds
for ($yPos = 0; $yPos < $h; $yPos++) {
for ($xPos = 0; $xPos < $w; $xPos++) {
// Check, ob Pixel nicht vollständig transparent ist
$rgb = imagecolorat($img, $xPos, $yPos);
if (imagecolorsforindex($img, $rgb)['alpha'] < 127) {
if ($xPos < $bounds['left']) {
$bounds['left'] = $xPos;
}
if ($xPos > $bounds['right']) {
$bounds['right'] = $xPos;
}
if ($yPos < $bounds['top']) {
$bounds['top'] = $yPos;
}
if ($yPos > $bounds['bottom']) {
$bounds['bottom'] = $yPos;
}
}
}
}
return $bounds;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.