Как преобразовать строку png base64 в пиксельный массив, не используя canvas getImageData?

Хотя кажется, что этот вопрос задавался ранее, люди полагаются на холст для этого преобразования. Проблема идет от URL base64, как это:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAFElEQVQIW2NkYGD4D8RYAeOQkgQAERQHAbuZaGoAAAAASUVORK5CYII=

в массив пикселей с интенсивностью цвета, как этоvar array = [ [0x00,0x00,0x00], ... 49 times ]; для изображения размером 7 на 7 пикселей (в данном случае черным) мы должны использовать такой код:

var mCanvas = document.createElement('canvas');
var base64DataUrl = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAFElEQVQIW2NkYGD4D8RYAeOQkgQAERQHAbuZaGoAAAAASUVORK5CYII=";
mCanvas.width = 7;
mCanvas.height = 7;
var mContext = mCanvas.getContext('2d');
var myImage = new Image();
myImage.setAttribute("src", base64DataUrl);
myImage.onload = function() { 
    var mContext = mCanvas.getContext('2d');
    var mImgData = mContext.getImageData(0,0,mCanvas.width,mCanvas.height);
}

который становится асинхронным из-зав процессе и очень больно работать (хотя это работает).

Тогда мы будем использовать такой код, чтобы получить цвета RGBA из canvas

function convertCanvasToPixelsArray(mCanvas){
    var mContext = mCanvas.getContext('2d');
    console.log(mCanvas.width);
    var mImgData = mContext.getImageData(0,0,mCanvas.width,mCanvas.height);

    var srcIndex=0, dstIndex=0, curPixelNum=0;
    var pixelsArray = new Array(mCanvas.width*mCanvas.height);
    for (curPixelNum=0; curPixelNum<mCanvas.width*mCanvas.height;  curPixelNum++)
    {
        pixelsArray[dstIndex] = new Array(3);
        pixelsArray[dstIndex][0] = mImgData.data[srcIndex]; // r
        pixelsArray[dstIndex][1] = mImgData.data[srcIndex+1];   // g
        pixelsArray[dstIndex][2] = mImgData.data[srcIndex+2];   // b

        dstIndex += 1;
        srcIndex += 4;
    }
    return pixelsArray;
}

Есть ли способ просто преобразовать из строки изображения Base64 PNG в массив, как указано выше, без холста? Я пробовал PNG.js, который говорит, что png поврежден или неполон (и я пробовал с или безdata:image/png;base64,, Я пробовал большинство из base64.js, и я беру байты, которые не имеют никакого смысла. Я пробовал звонки atob / btoa без соответствующих результатов.

Ответ на этот вопрос (Возможно ли считывать данные пикселей из изображений base64?) должен был работать, но я получаю (только для нового PNG (данные)):

Uncaught Error: Incomplete or corrupt PNG file 

с моим примером:

function show(data){
        var png = new PNG(data);
        var img = document.getElementById('image'), limg = document.getElementById('largeimage');
        document.getElementById('nativeimage').src = 'data:image/png;base64,' + data;
        img.innerHTML = '';
        limg.innerHTML = '';
        img.style.width = png.width + 'px';
        img.style.height = png.height + 'px';
        limg.style.width = (png.width * 3) + 'px';
        limg.style.width = (png.height * 3) + 'px';
        var line;
        while(line = png.readLine())
        {
            for (var x = 0; x < line.length; x++){
                var px = document.createElement('div'), px2 = document.createElement('div');
                px.className = px2.className = 'pixel';
                px.style.backgroundColor = px2.style.backgroundColor = '#' + line[x].toString(16).padRight('0', 6);
                img.appendChild(px);
                limg.appendChild(px2);
            }
        }
    }


    show("iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAFElEQVQIW2NkYGD4D8RYAeOQkgQAERQHAbuZaGoAAAAASUVORK5CYII=");

или пример в этом вопросе. Я использую этот PNG.js: [Я больше не использую это]https://github.com/devongovett/png.js/blob/master/png.js

РЕДАКТИРОВАТЬ Два пакета не совпадают - посмотрим!

РЕДАКТИРОВАТЬ 2 это почти сработало, используя этоhttp://jsfiddle.net/6VqwC/8/ из другого вопросаНО если ты пойдешь, то увидишь, что моя черная плитка становится полосамисиний, зеленый, красный - это ошибка пакета: /?

РЕДАКТИРОВАТЬ 3 так что кажется, что пакет работает со сжатыми pngs - и мои pngs не сжаты - есть ли способ использовать PNG.js с несжатыми файлами?

РЕДАКТИРОВАТЬ 4 Так что, если я сделаю функцию (как в ответе, который был удален):

function convertBase64ToPixelsArray(tile,whatToDoNext){
        var base64DataUrl = tile.base64DataUrl;
        var mCanvas = newEl("canvas");
        var ctx = mCanvas.getContext("2d");
        var pixelsArray = [];

        var img = newEl("img");
        img.onload = getRGB;
        img.src = base64DataUrl;

        function getRGB(){
            mCanvas.width = img.width;
            mCanvas.height = img.height;
            ctx.drawImage(img,0,0);
            var data = ctx.getImageData(0,0,mCanvas.width, mCanvas.height).data;
            for (var i=0; i<data.length; i+=4){
                pixelsArray.push([data[i],data[i+1],data[i+2]]);
            }
            whatToDoNext(pixelsArray);
        }
    }

и иметь несколько разных функций, таких как эти:

function doSomethingWithTile(tile,params){
   convertBase64ToPixelsArray(tile,function(pixelsArray){
    //manipulate the pixels 
    //convert them back to base64 and store it in the tile
    tile.base64UrlData = convertPixelsArrayToCanvas(pixelsArray,tile.width,tile.height).convertToBase64();
    });
}

тогда, когда я делаю это

var tile = initialize_tile();
doSomethingWithTile(tile,params1);
doSomethingWithTile2(tile,params2);
doSomethingWithTile(tile,params1);
...

то, что происходит, - то, что начальная плитка управляется так, чтобы эффекты не накапливались. Если вы можете помочь мне с этим, у меня есть ответ, который будет использовать холст. Очередь вызовов doSomethingWithTile не является предопределенной / статической и может быть произвольной

Я действительно сбит с толку, и я был бы очень признателен за вашу помощь :) Заранее спасибо!

Ответы на вопрос(0)

Ваш ответ на вопрос