【问题标题】:How to get cropped image length correctly?如何正确获得裁剪的图像长度?
【发布时间】:2019-11-07 07:20:56
【问题描述】:

我想用this code 裁剪上传的图片。

另外,我想限制图像的大小(以字节为单位)并将其保存为 png 格式。 当我不使用裁剪后的图像时,我可以使用以下代码获取图像长度:

var postedFile = Request.Files["FileUpload1"];
long length=postedFile.ContentLength;

我的问题是我无法正确获得裁剪后的图像长度。如果我在Upload 函数中使用bytes.Length,它会得到大于来自 FileUpload 控件的原始图像长度的长度。 如何获得 png 格式的裁剪图像长度?

我的代码如下:

    <script type="text/javascript" 
    src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"> 
    </script>
    <script type="text/javascript" src="http://jcrop- 
    cdn.tapmodo.com/v0.9.8/js/jquery.Jcrop.js"></script>
    <script type="text/javascript">
        $(function () {
            $('#FileUpload1').change(function () {
                $('#Image1').hide();
                var reader = new FileReader();
                reader.onload = function (e) {
                    $('#Image1').show();
                    $('#Image1').attr("src", e.target.result);
                    $('#Image1').Jcrop({
                        onChange: SetCoordinates,
                        onSelect: SetCoordinates
                    });
                }
                reader.readAsDataURL($(this)[0].files[0]);
            });

            $('#btnCrop').click(function () {
                var x1 = $('#imgX1').val();
                var y1 = $('#imgY1').val();
                var width = $('#imgWidth').val();
                var height = $('#imgHeight').val();
                var canvas = $("#canvas")[0];
                var context = canvas.getContext('2d');
                var img = new Image();
                img.onload = function () {
                    canvas.height = height;
                    canvas.width = width;
                    context.drawImage(img, x1, y1, width, height, 0, 0, width, height);
                    $('#imgCropped').val(canvas.toDataURL());
                    $('[id*=btnUpload]').show();
                };
                img.src = $('#Image1').attr("src");
            });
        });
        function SetCoordinates(c) {
            $('#imgX1').val(c.x);
            $('#imgY1').val(c.y);
            $('#imgWidth').val(c.w);
            $('#imgHeight').val(c.h);
            $('#btnCrop').show();
        };
    </script>

    <input type="file" id="FileUpload1" name="FileUpload1"  />
    <br />
    <br />
    <table border="0"  cellpadding="0" cellspacing="5" style="text-align:right">
     <tr >
     <td>
     <img id="Image1" alt="" style="display: none" />
     <br />
     <canvas id="canvas" height="5" width="5"></canvas>
     </td>
     </tr>
    </table>
    <br />
     <input type="button" class="button" id="btnCrop" value="crop" style="display: none" />
     <asp:Button ID="btnUpload" CssClass="button" runat="server" Text="upload" OnClick="Upload" Style="display: none" />
     <input type="hidden" name="imgX1" id="imgX1" />
     <input type="hidden" name="imgY1" id="imgY1" />
     <input type="hidden" name="imgWidth" id="imgWidth" />
     <input type="hidden" name="imgHeight" id="imgHeight" />
     <input type="hidden" name="imgCropped" id="imgCropped" />

在后面的代码中:

    var postedFile = Request.Files["FileUpload1"];
    if (postedFile != null && postedFile.ContentLength > 0)
    {
        string filename = postedFile.FileName;
        FileInfo fi = new FileInfo(filename);
        string ext = fi.Extension;
        if (ext != ".png")
         {
            lblMessage.Text = "please upload .png file";
             return;
         }
         long length=postedFile.ContentLength;//this line return original length correctly
         string base64 = Request.Form["imgCropped"];
         byte[] bytes = Convert.FromBase64String(base64.Split(',')[1]);
         int length= bytes.Length //get copped image length, but it greater than orig size
         using (System.IO.FileStream stream = new System.IO.FileStream(path + "\\" + filename, System.IO.FileMode.Create))
         {
              stream.Write(bytes, 0, bytes.Length);
              stream.Flush(); 
         }

更新: 我尝试不同质量(1,0.95,...)和 png 和 jpeg 格式的 canvas.toDataURL(),并在选择整个图像时检查裁剪的图像长度,但这个长度与原始图像不同。 (如果我在裁剪图像中选择原始图像的 75% 像素,我想获得原始长度的 75% 的长度。) 设置质量和格式以获得与原始图像相同的质量的原因和价值是什么?

【问题讨论】:

  • 你能发布你用来裁剪图像的代码吗?
  • 我完全使用上面链接中描述的代码。
  • 直接在此处发布相关部分,而不是作为链接。人们通常不倾向于点击外部链接,因此代码真的“不算数”。
  • 上传的原始图像的质量是否低于用于编码裁剪版本的质量?例如,我可以下载一个 25k 的 jpg,稍微裁剪一下,然后以 100% 的质量将其保存为 100k png。您的代码将默认质量设置传递给toDataURL,您可以将格式和质量显式设置为与上传文件相同的格式和质量。另见stackoverflow.com/questions/14383557/…
  • 代码应该在问题中,而不是链接到场外,以保持问题的长期价值。

标签: c# asp.net


【解决方案1】:

您的问题不在于您获得的长度不正确,而是您使用比您裁剪的原始图像更高的质量设置来压缩裁剪的图像。

考虑为.toDataURL 明确设置格式和质量选项

如果您愿意,您可以使用与原始文件相同的设置,如果尺寸更小,应该会导致文件更小(可能标题大小占主导地位的非常小的图像除外。)

默认类型为image/png,默认质量值为0.92,这可能是较小图像(因为您将其裁剪了一点)的文件大小可能比原始未裁剪图像更大的原因;因为裁剪后的图像是使用比源图像更高质量的设置编码的。

例如,如果裁剪量导致裁剪后的图像是原始图像像素数的 75%,但这些像素随后会使用(平均而言)使用的方案进行编码2 倍 字节数作为原始编码,则裁剪后的文件将约为原始长度的 150%。 我提供这个例子来说明如何使裁剪后的文件比未裁剪的文件更大。

摘自the documentation for canvas.toDataURL:

canvas.toDataURL(type, encoderOptions);

type(可选)指示图像格式的 DOMString。默认 格式类型为图像/png。

encoderOptions(可选)0 之间的数字 和 1 表示用于图像格式的图像质量 有损压缩,例如 image/jpeg 和 image/webp。如果这个说法 是其他任何东西,使用图像质量的默认值。这 默认值为 0.92。其他参数被忽略。

【讨论】:

  • 在 canvas.toDataURL() 中必须使用哪些值才能获得与原始图像相同质量的裁剪图像?请用代码解释。
  • 我测试了 canvas.toDataURL("image/jpeg",1) 但这也让我的长度大于原始尺寸。
  • 1 是最大质量(最大文件大小)。要获得较小的文件大小,您必须将质量降低到较低的数字。你尝试过更小的数字吗?您关于如何确定现有质量的后续问题已经回答here 或者只是决定您的质量应该是什么并将其绝对设置为 0.5。 Jpeg 质量确实下降到 50% 以下,因此您必须根据自己的要求做出设计决定。
猜你喜欢
  • 2013-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
相关资源
最近更新 更多