Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
185 views
in Technique[技术] by (71.8m points)

javascript - How to read a image file using AJAX and render to Canvas?

I want to read a image from my own server using Ajax and render that to Canvas.

Now I know that this can be achieved using normal image tags and canvas draw like shown below :

<img id="myImage" src="./ColorTable.PNG" style="display:none;"/>
var img = document.getElementById('myImage'); 
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);

But I don't want to use it and instead was looking if we can read the file using a Ajax call for the image src location and then render it to canvas , but for me it just shows a wrong image : Here's what I did :

var xhr = new XMLHttpRequest();
xhr.open('GET', './ColorTable.PNG', true);
xhr.responseType = 'arrayBuffer';
xhr.onload = function(e) {
    var data = this.response;
    var buf = new ArrayBuffer(data.length);
    var bufView = new Uint8Array(buf);
    for (var index = 0; index < data.length; index++) {
        bufView[index] = data.charCodeAt(index);
    }
    //initialize and get context and then render the image
    var ctx = canvas.getContext('2d');
    var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    for (var  i = 0 ; i < imgData.data.byteLength; i++) {
        imgData.data[i] = bufView[i];
        imgData.data[i++] = bufView[i];
        imgData.data[i++] = bufView[i];
        imgData.data[i++] = 255;
    }
    ctx.putImageData(imgData, 0, 0);
};
xhr.send();

But the second approach doesn't work for me as the image that is rendered is a wrong one . Can anybody help?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are trying to copy data from a un-parsed binary PNG file to the canvas which of course won't work as the PNG contains chunks and other data, and the image itself is compressed binary data which has to be deflated. Loading via AJAX won't parse the PNG, it will simply be treated as a raw binary file as any other file and the result will be random colored noise.

You have to load the PNG and use it as a source for an image element which will take care of parsing and deflating, then draw the image element to canvas (unless you want to parse the file manually, which is do-able).

You could simply load the image directly as you say, without the need for AJAX:

var img = new Image();
img.onload = function() {
    var ctx = canvas.getContext('2d');
    ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
    // next step here...
};
img.src = url;

There is no difference between these methods in terms of getting the pixel data later - in both cases CORS requirements must be fulfilled.

However, if you for some reason absolutely need AJAX (which makes no sense as you would still have to pass it through an image element): load the image data as a Blob instead of ArrayBuffer, then create an object-URL for it which can be used as image source for an image element:

var xhr = new XMLHttpRequest();
xhr.open('GET', './ColorTable.PNG', true);
xhr.responseType = 'blob';                        // we want a blob
xhr.onload = function(e) {
    var url = URL.createObjectURL(this.response); // ! URL may need prefix
    var img = new Image();
    img.onload = function() {
        URL.revokeObjectURL(this.src);            // auto-revoke can be set in some browsers
        var ctx = canvas.getContext('2d');
        ctx.drawImage(this, 0, 0, canvas.width, canvas.height)
    };
    img.src = url;

};
xhr.send();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...