将画布作为 jpg 文件保存到服务器时如何增加 DPI?

Posted

技术标签:

【中文标题】将画布作为 jpg 文件保存到服务器时如何增加 DPI?【英文标题】:How to increase DPI when saving a canvas to the server as a jpg file? 【发布时间】:2016-06-27 00:00:21 【问题描述】:

*** 上的新功能。我正在研究一个解决方案,我可以在服务器上使用 jcrop 将裁剪后的图像保存为 .jpg 文件。该图像还用作立方体表面上的纹理(我为此使用了three.js)。我不是专业的编码员,但我已经设法将图片放在表面并保存在服务器上。

但是,不幸的是,这些文件的分辨率始终为 96 DPI,质量很差(即使分辨率为 2000 像素 X 2000 像素)。我试图找到一个解决方案,但我仍然希望找到更现代的东西。例如,我听说过 toDataURLHD 方法。我试过了,但是没有用。

这是我用于服务器上传的 javascript 代码:

    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);

还有 PHP 部分:

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 );


代码有效,我在服务器上得到图像,但质量很差:

Original Image

Cropped Image

有什么办法可以获得更多的dpi?

编辑:

我的代码有点复杂,因为我使用了外部资源。例如,画布标签是“隐藏的”。这里还有一些上传过程的代码。

html

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

<!--Opens a popup, where the picture is being cropped-->
<div id="popup" class="popup">
<img src="" id="target"  />
<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>

所以在这里我找不到任何画布标签。但我知道,它是生成的,我在“Iconcontroller”函数内的一个 .js 文件中找到它。

EDIT2:

我想我找到了我应该修改它的部分。我尝试了canvas.width=img.width*300/96 方法,但有些东西不起作用。可能代码放错地方了。

这里是完整的代码。注意RESIZING AND UPLOADupdate image canvas 部分:

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;
                                elseSIZES_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();
                                    ;

                                
            );
        

我还用代码创建了一个 ZIP 文件,因为有一些库。 Here is the link.

EDIT3:

不知道markE 的答案去了哪里,但无论如何。解决方案很好,我希望我能设法在我的代码中实现它。感谢您的努力,我真的很感激,因为我是新来的,甚至没想到会得到任何答案。 :)

【问题讨论】:

您需要做的只是上传原始图像而不做任何修改,这样您就不会丢失质量或引入不需要的工件。调整图像大小会产生伪影,并且会因不同的硬件和浏览器配置而有所不同您无法提高图像质量,因此如果用于打印,您必须按原样接受它并让打印驱动程序处理 DPI,因为他们的软件很多更好地将像素调整为点。 我只是想在读完这篇文章后找到一些东西。我有图片,质量很好,但 dpi 也很低,比如 96 甚至更低。但无论如何,当我对它们进行裁剪时,它们之后都变得模糊了。这是为什么?并且图片始终导出为 96 dpi,即使它具有更大或更低的 dpi。我还假设它应该保存正确的质量,但它不会发生。我认为关键与 jcrop 有关,不幸的是它提供了低图像质量......:( 【参考方案1】:

您需要更多像素才能获得足够的打印机分辨率。

一种方法(正如 Blindman67 所说)是从原始图像中裁剪,然后让打印机放大到所需的像素数。

您也可以手动添加像素...

方法如下:

如果您需要添加像素,您可以创建第二个更大的画布,并使用 drawImage 的缩放版本进一步缩放裁剪部分。如果原始图像的分辨率不是打印机分辨率,您可能需要使用此技术。

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);

【讨论】:

以上是关于将画布作为 jpg 文件保存到服务器时如何增加 DPI?的主要内容,如果未能解决你的问题,请参考以下文章

如何将内联 svg(在 DOM 中)绘制到画布上?

将画布图像保存到主机服务器

将 WPF 画布保存到文件而不损失质量(不使用位图作为中介)

如何将画布数据保存到文件

如何将画布数据保存到文件

如何将 CorePlot 创建的图形保存为 jpg 文件