Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loss of quality while adding drawing image on HTML 5 canvas from binary string

I am trying to draw an image from binary string on to the canvas.

 var reader = new FileReader();
     //reader.readAsDataURL(file);
     reader.readAsBinaryString(file);
     reader.onload = function(event){
         var d = $(thisObj.CreateIndoorFormDivControlName).dialog();
         var canvas =document.getElementById('canvasfloorLayout');
        var cxt=canvas.getContext("2d");
         var img=new Image();
            img.onload = function() {
                cxt.drawImage(img, 0, 0,canvas.width,canvas.height);
            }
            img.src = "data:image/jpeg;base64,"+window.btoa(reader.result);

I am using the above code but the problem is the image size is getting reduced to the canvas size and quality is dropping like anything. I have been tried with

cxt.drawImage(img, 0, 0,img.width,img.height);

But the image gets cropped. I donot want to use reader.readAsDataURL as I need to post the binary to the server. My requirement is to show the full image and draw lines on it .

like image 929
Abhik Avatar asked Sep 02 '25 05:09

Abhik


1 Answers

canvas.width  = img.width;
canvas.height = img.height;

ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

...if you draw the image at the canvas' native resolution, then when the image gets scaled, it's obviously going to lose quality.

...if you draw the image at the image's native resolution, but the canvas hasn't changed size, then you're going to end up with a partial image, or a partially-filled canvas.

So if you want neither of those, then set the dimensions of the canvas to match the dimensions of the image, and you'll have a canvas-drawn image which matches the resolution of the data-image.


EDIT

Adding an example of a proxy, between the two.

var img = new Image(),
    canvas = document.createElement("canvas"),
    context = canvas.getContext("2d"), 
    // ......etc


    dimensions = {
        max_height : 800,
        max_width  : 600,
        width  : 800, // this will change
        height : 600, // this will change
        largest_property : function () {
            return this.height > this.width ? "height" : "width";
        },
        read_dimensions : function (img) {
            this.width = img.width;
            this.height = img.height;
            return this;
        },
        scaling_factor : function (original, computed) {
            return computed / original;
        },
        scale_to_fit : function () {
            var x_factor = this.scaling_factor(this.width,  this.max_width),
                y_factor = this.scaling_factor(this.height, this.max_height),

                largest_factor = Math.min(x_factor, y_factor);

            this.width  *= largest_factor;
            this.height *= largest_factor;
        }
    };


dimensions.read_dimensions(img).scale_to_fit();

canvas.width  = dimensions.width;
canvas.height = dimensions.height;
context.drawImage(img, 0, 0, dimensions.width, dimensions.height);
like image 198
Norguard Avatar answered Sep 04 '25 20:09

Norguard