簡體   English   中英

透明HTML5 canvas todataurl僅在移動設備上呈現透明背景

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM