How to increase DPI when saving a canvas to the server as a jpg file?
Asked Answered
C

1

6

New here on Stackoverflow. I am working on a solution, where I can save a cropped image using jcrop on the server as a .jpg file. The image is also used as a texture on a cube surface (I am using three.js for that). I am not a professional coder, but I have managed to get the picture on the surface and save it on the server.

BUT, unfortunately the files have always a 96 DPI resolution and have a poor quality (even with a 2000px X 2000px resolution). I tried to find a solution and I am still hoping to find something more contemporary. I heard about the toDataURLHD method for example. I tried it, but it didn't work.

Here is my Javascript code for the server upload:

    function saveIt(){
var data_image_1=$('#img_front1_CANVAS_PREVIEW')[0].toDataURL('image/jpeg');
var postData = "canvasData="+data_image_1;
var ajax = new XMLHttpRequest();
ajax.open("POST",'upload.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.onreadystatechange=function()
{
    if (ajax.readyState == 4)
    {alert("image saved");}
}
ajax.send(postData);
}

And the PHP part:

if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
    $rawImage=$GLOBALS['HTTP_RAW_POST_DATA'];
    $removeHeaders=substr($rawImage, strpos($rawImage, ",")+1);
    $decode=base64_decode($removeHeaders);
    $fopen = fopen( 'uploads/myImage.jpg', 'wb' );
    fwrite( $fopen, $decode);
    fclose( $fopen );

}

The code works, I get the image on the server, but the quality is poor:

Original Image

Cropped Image

Is there any way to get more dpi?

EDIT:

My code is a little complex since I used external resources. The canvas tag was "hidden" for example. Here also some code of the upload procedure.

HTML:

<!--Upload Button-->
<img class="email-avatar" id="img_front1" height="64" width="64" src="img.png">

<!--Opens a popup, where the picture is being cropped-->
<div id="popup" class="popup">
<img src="" id="target" alt="Flowers" />
<button  onclick="javascript:$.modal.close();"  class="pure-button primary-button" id="Ready">Ready</button>
</div>

<!--After the cropping this function is called-->

<script>
// icon image search
jQuery(document).ready(function($){
Iconcontroller('img_front1',2000,2000,0);
});
</script>

So here I couldn't find any canvas tags. But I know, it was generated, and I found it in a .js file within the "Iconcontroller" function.

EDIT2:

I think I found the part where I should modify it. I tried the canvas.width=img.width*300/96 method, but something doesn't work. Maybe the code is not on the right place in this.

Here the full code. Look after the RESIZING AND UPLOAD and update image canvas parts:

Javascript:

function Iconcontroller(OBJ_ICON_ID,SIZE_W,SIZE_H,SIZES_WH,FUNCTIONCALLBACK){

            // CONSTANTS AUX
            var NAME_OBJECT_CONTROL=OBJ_ICON_ID;
            var NAME_FILE_INPUT=NAME_OBJECT_CONTROL+'_FILES_INPUT';
            var NAME_PREVIEW_CANVAS=NAME_OBJECT_CONTROL+'_CANVAS_PREVIEW';

            var NAME_TARGET_IMG='target';
            var NAME_POPUP_HTML='popup';
            var SIZE_W=SIZE_W;
            var SIZE_H=SIZE_H;
            var SIZES_WH=SIZES_WH;


            $( "#"+NAME_OBJECT_CONTROL).after( '<input  name="'+NAME_FILE_INPUT+'" style="display:none" id="'+NAME_FILE_INPUT+'" type="file" accept="image/jpeg,image/png,image/gif" />' );
            $( "#"+NAME_OBJECT_CONTROL).after( '<canvas id="'+NAME_PREVIEW_CANVAS+'" style="display:none"></canvas>' );
            $('#'+NAME_OBJECT_CONTROL).click(
            function(){
                $('#'+NAME_FILE_INPUT).val("");
                $('#'+NAME_FILE_INPUT).click();
            });

            $('#'+NAME_FILE_INPUT).change(function(e) {
                var file = e.target.files[0];
                ProcessImage(file,NAME_PREVIEW_CANVAS,NAME_TARGET_IMG,NAME_POPUP_HTML,SIZE_W,SIZE_H,SIZES_WH,FUNCTIONCALLBACK);
            });

        }

        function modal(NAME_POPUP_HTML){
                $("#"+NAME_POPUP_HTML).modal({escapeClose: true,clickClose: true,showClose: true});
        }

        //PROCESS AND RESIZE FUNCTION 
        function ProcessImage(file,NAME_PREVIEW_CANVAS,NAME_TARGET_IMG,NAME_POPUP_HTML,SIZE_W,SIZE_H,SIZES_WH,FUNCTIONCALLBACK){

            var NAME_PREVIEW_CANVAS=NAME_PREVIEW_CANVAS;
            var NAME_TARGET_IMG=NAME_TARGET_IMG;
            var NAME_POPUP_HTML=NAME_POPUP_HTML;
            var SIZE_W=SIZE_W;
            var SIZE_H=SIZE_H;

            //RESIZING AND UPLOAD
            canvasResize(file, {
                        width: 710,
                        height: 470,
                        crop: false,
                        quality:100,
                        rotate: 0,
                        callback: function(data, width, height) {
                        // resizing img
                        var span = $('#'+NAME_TARGET_IMG).attr('src',data);
                        // detect crop
                        jcrop_obj= $('#'+NAME_TARGET_IMG).data('Jcrop');
                        // show popup
                        $("#"+NAME_POPUP_HTML).modal({
                                escapeClose: true,
                                clickClose: true,
                                showClose: true
            });
            // si existe para cambiar el crop   
            if (jcrop_obj != null) {$('#'+NAME_TARGET_IMG).data('Jcrop').destroy()}

                                if(SIZES_WH!=1){SIZES_WH=SIZE_W /SIZE_H;}
                                else{SIZES_WH=0;}

                                // crea el jcrop for image
                                $('#'+NAME_TARGET_IMG).Jcrop({
                                    aspectRatio: SIZES_WH,
                                    onChange : updatePreview,
                                    onSelect : updatePreview,
                                    setSelect: [ 0, 0, SIZE_W, SIZE_H]
                                });
                        // update image canvas
                        function updatePreview(c) { 
                                if(parseInt(c.w) > 0) {
                                    var imageObj = $("#"+NAME_TARGET_IMG)[0];
                                    // Show image preview
                                    var canvas = $("#"+NAME_PREVIEW_CANVAS)[0];
                                    canvas.width  = SIZE_W*300/96;
                                    canvas.height = SIZE_H*300/96;
                                    var context = canvas.getContext("2d");                      
                                                    context.drawImage(imageObj, c.x, c.y, c.w, c.h, 0, 0, SIZE_W*300/96, SIZE_H*300/96);
                                                }
                                            if(FUNCTIONCALLBACK){FUNCTIONCALLBACK();}
                                    };

                                }
            });
        }

I also created a ZIP File with the codes, since there are some libaries. Here is the link.

EDIT3:

Don't know where the answer from markE went, but anyway. The solution was nice, I hope I will manage to implement it to my code. Thank you for your efforts, I really appreciate it, since I am new here and didn't even expected to get any answer. :)

Casino answered 11/3, 2016 at 16:33 Comment(2)
What you need to do is just upload the original image without any modification, that way you do not lose quality or introduce unwanted artifacts. Resizing the image will create artifacts and will be different for different hardware and browser configurations You can not improve the image quality so if it is for print you have to accept it as it is and let the print drivers handle the DPI as their software is much better as adapting pixels to dots.Wenzel
I just tried to find something out after I read this. I had pictures, that had good quality, but also low dpi, like 96 or even lower. But anyway, when i jcrop them, they are all blurry afterwards. Why is that? And the picture is always exported to 96 dpi, even if it had bigger or lower dpi. I would also assume, that it should save the right quality, but it doesn't happen. I think the key has something to do with jcrop, that it provides unfortunately low image quality...:(Casino
S
0

You need more pixels to get to adequate printer resolution.

One way (as Blindman67 says) is to crop from your original image and let the printer scale-up to the required number of pixels.

You can also add pixels manually...

Here's how:

If you need to add pixels, you can create a second canvas that is even larger and use the scaling version of drawImage to scale the cropped portion up further. You might need to use this technique if the resolution of your original image is not printer resolution.

function scaleUp(img,scale){
    var w=img.width*scale;
    var h=img.height*scale;
    var c=document.createElement('canvas');
    cctx=c.getContext('2d');
    c.width=w;
    c.height=h;
    cctx.drawImage(img,0,0,img.width,img.height,0,0,w,h);
    var img1=new Image();
    img1.src=c.toDataURL('image/jpeg',100);
    document.body.appendChild(img1);
}
Surname answered 14/3, 2016 at 7:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.