Jak przekonwertować łańcuch p64 base64 na tablicę pikseli bez użycia canvas getImageData?
Chociaż wydaje się, że to pytanie zostało zadane wcześniej, ludzie polegają na płótnie przy tej konwersji. Problem idzie z adresu URL base64 w następujący sposób:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAFElEQVQIW2NkYGD4D8RYAeOQkgQAERQHAbuZaGoAAAAASUVORK5CYII=
do tablicy pikseli o takich intensywnościach kolorówvar array = [ [0x00,0x00,0x00], ... 49 times ];
dla obrazu 7px by 7px (w tym przypadku czarny) musimy użyć kodu takiego jak ten:
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);
}
który staje się asynchroniczny z powoduonload i bardzo bolesna praca (choć działa).
Następnie użylibyśmy takiego kodu, aby uzyskać kolory RGBA z płótna
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;
}
Czy istnieje sposób, aby po prostu przekonwertować z obrazu Base64 png na tablicę taką jak powyżej bez kanwy? Próbowałem pliku PNG.js, który mówi, że png jest uszkodzony lub niekompletny (i próbowałem z lub bezdata:image/png;base64,
. Próbowałem większości base64.js i biorę bajty, które nie mają sensu. Próbowałem wywoływać atob / btoa bez żadnych istotnych wyników.
Odpowiedź na to pytanie (Czy można odczytać dane pikseli z obrazów base64?) powinno działać, ale dostaję (tylko dla nowego PNG (dane)):
Uncaught Error: Incomplete or corrupt PNG file
z moim przykładem:
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=");
lub przykład w tym pytaniu. Używam tego pliku PNG.js: [Już go nie używam]https://github.com/devongovett/png.js/blob/master/png.js
EDYTOWAĆ Oba pakiety nie są takie same - zobaczmy!
EDYCJA 2 prawie to zadziałałohttp://jsfiddle.net/6VqwC/8/ z drugiego pytaniaALE jeśli pójdziesz, zobaczysz, że moja czarna płytka staje się paskaminiebieski, zielony, czerwony - czy to błąd pakietu: /?
EDYCJA 3 więc wydaje się, że pakiet działa ze skompresowanymi png - a moje png nie są kompresowane - czy istnieje sposób na użycie PNG.js z nieskompresowanymi plikami?
EDYCJA 4 Jeśli więc zrobię funkcję (jak w usuniętej odpowiedzi):
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);
}
}
i mają wiele różnych funkcji, takich jak:
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();
});
}
wtedy kiedy to robię
var tile = initialize_tile();
doSomethingWithTile(tile,params1);
doSomethingWithTile2(tile,params2);
doSomethingWithTile(tile,params1);
...
dzieje się tak, że początkowa płytka jest manipulowana, więc efekty nie kumulują się. Jeśli możesz mi w tym pomóc, to mam odpowiedź, która użyje płótna. Kolejka połączeń doSomethingWithTile nie jest predefiniowana / statyczna i może być dowolna
Jestem naprawdę zaskoczony i naprawdę będę wdzięczny za pomoc :) Z góry dziękuję!