调整图像大小,需要一个好的库 [英] Resize image, need a good library

查看:87
本文介绍了调整图像大小,需要一个好的库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先-问题


我正在开发一个Web应用程序,该应用程序使用户能够使用智能手机,平板电脑拍照或仅在PC上浏览图片.我需要将此文件上传到我的数据库,该数据库可以很好地运行如果,图片足够小.

在对某些照片进行了一些试验之后,我发现智能手机拍摄的照片至少具有1MB的大小,这也是将照片上传到我的数据库的一种方法.

上传过程如下:
1.将图像转换为Base64编码的字符串.
2.将数组中的字符串(包含多个字符串)发送到WebAPI
3.将字符串合并为一个,并将其转换为字节数组.

我注意到,如果文件大小约为70-90kb,这将是可以插入数据库的文件的最大大小.当我有一个大于100kb的文件时,插入失败.

因此,我正在寻找一个不错的调整大小的库来调整所选图片的大小.我什至不知道这是否有可能,但是一切都必须在客户端完成.

技术


我在客户端使用Javascript/jQuery和AngularJS,在WebAPI中使用VB.NET.这是因为我正在实习,并且没有其他选择来使用VB.NET.

但这与问题无关,我只需要找到一种压缩/调整大小/最小化所选文件的方法,就可以将其上传到数据库中.

上传是通过AngularJS的$ http.post()完成的.

如果有人可以建议一个库,是否愿意提供一些基本的示例代码来帮助其他程序员?我几乎很难弄清楚如何使用插件或库,因为我对这一切还很陌生.如果你们能为我提供至少一些信息以使我步入正轨,我将不胜感激.

提前谢谢!

很抱歉,我无法提供任何代码或其他内容,它比编码问题更能提供参考.当我有一个可以使用的库时,可能会弹出此窗口.另外,如果有任何评论,我会考虑的,因为我有最后期限,没有太多时间开始解决小问题.到目前为止,大多数功能都可以使用,除了该图像问题.

解决方案

您可以使用 HTML5画布元素以在其上放大图像,然后适当调整其大小

您可以即时创建一个canvas并对其执行像素操作-所以不用担心它在DOM上的任何地方都不可见-像虚拟画布一样思考

这是我前一段时间写的一个小脚本(在我不太记得的另一个SO问题的帮助下)-允许您执行此操作-同时保持图像的长宽比:

参数

  • 您直接在其中提供image
  • 您提供一个maxWidth/maxHeight,它将至少保留 2个中的一个
  • 它还允许您通过定义degrees参数来旋转图像(这在移动设备上非常有用,因为不同的设备会提供任意旋转的图像-您会发现这很困难如果您要使用移动设备,请尽快找到方法)

返回

  • 它返回调整大小后的图像的 Base64 字符串

function resizeImg(img, maxWidth, maxHeight, degrees) {
  var imgWidth = img.width,
    imgHeight = img.height;

  var ratio = 1,
    ratio1 = 1,
    ratio2 = 1;
  ratio1 = maxWidth / imgWidth;
  ratio2 = maxHeight / imgHeight;

  // Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
  if (ratio1 < ratio2) {
    ratio = ratio1;
  } else {
    ratio = ratio2;
  }
  var canvas = document.createElement("canvas");
  var canvasContext = canvas.getContext("2d");
  var canvasCopy = document.createElement("canvas");
  var copyContext = canvasCopy.getContext("2d");
  var canvasCopy2 = document.createElement("canvas");
  var copyContext2 = canvasCopy2.getContext("2d");
  canvasCopy.width = imgWidth;
  canvasCopy.height = imgHeight;
  copyContext.drawImage(img, 0, 0);

  // init
  canvasCopy2.width = imgWidth;
  canvasCopy2.height = imgHeight;
  copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);


  var rounds = 1;
  var roundRatio = ratio * rounds;
  for (var i = 1; i <= rounds; i++) {


    // tmp
    canvasCopy.width = imgWidth * roundRatio / i;
    canvasCopy.height = imgHeight * roundRatio / i;

    copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);

    // copy back
    canvasCopy2.width = imgWidth * roundRatio / i;
    canvasCopy2.height = imgHeight * roundRatio / i;
    copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);

  } // end for

  canvas.width = imgWidth * roundRatio / rounds;
  canvas.height = imgHeight * roundRatio / rounds;
  canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);


  if (degrees == 90 || degrees == 270) {
    canvas.width = canvasCopy2.height;
    canvas.height = canvasCopy2.width;
  } else {
    canvas.width = canvasCopy2.width;
    canvas.height = canvasCopy2.height;
  }

  canvasContext.clearRect(0, 0, canvas.width, canvas.height);
  if (degrees == 90 || degrees == 270) {
    canvasContext.translate(canvasCopy2.height / 2, canvasCopy2.width / 2);
  } else {
    canvasContext.translate(canvasCopy2.width / 2, canvasCopy2.height / 2);
  }
  canvasContext.rotate(degrees * Math.PI / 180);
  canvasContext.drawImage(canvasCopy2, -canvasCopy2.width / 2, -canvasCopy2.height / 2);


  var dataURL = canvas.toDataURL();
  return dataURL;
}


这是一个工作代码段,可让您从文件系统上载并即时调整大小:

 /*
-------------------------------
-------HANDLE FILE UPLOAD------
-------------------------------
*/

var input = document.getElementById('input');
input.addEventListener('change', handleFiles);

function handleFiles(e) {
  var img = new Image;
  img.src = URL.createObjectURL(e.target.files[0]);
  img.onload = function() {
    var base64String = resizeImg(img, 300, 300, 0); //HERE IS WHERE THE FUNCTION RESIZE IS CALLED!!!!
    alert(base64String);
    document.getElementById('previewImg').src = base64String;
  }
}



/*
-------------------------------
-------RESIZING FUNCTION-------
-------------------------------
*/


function resizeImg(img, maxWidth, maxHeight, degrees) {
  var imgWidth = img.width,
    imgHeight = img.height;

  var ratio = 1,
    ratio1 = 1,
    ratio2 = 1;
  ratio1 = maxWidth / imgWidth;
  ratio2 = maxHeight / imgHeight;

  // Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
  if (ratio1 < ratio2) {
    ratio = ratio1;
  } else {
    ratio = ratio2;
  }
  var canvas = document.createElement("canvas");
  var canvasContext = canvas.getContext("2d");
  var canvasCopy = document.createElement("canvas");
  var copyContext = canvasCopy.getContext("2d");
  var canvasCopy2 = document.createElement("canvas");
  var copyContext2 = canvasCopy2.getContext("2d");
  canvasCopy.width = imgWidth;
  canvasCopy.height = imgHeight;
  copyContext.drawImage(img, 0, 0);

  // init
  canvasCopy2.width = imgWidth;
  canvasCopy2.height = imgHeight;
  copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);


  var rounds = 1;
  var roundRatio = ratio * rounds;
  for (var i = 1; i <= rounds; i++) {


    // tmp
    canvasCopy.width = imgWidth * roundRatio / i;
    canvasCopy.height = imgHeight * roundRatio / i;

    copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);

    // copy back
    canvasCopy2.width = imgWidth * roundRatio / i;
    canvasCopy2.height = imgHeight * roundRatio / i;
    copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);

  } // end for

  canvas.width = imgWidth * roundRatio / rounds;
  canvas.height = imgHeight * roundRatio / rounds;
  canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);


  if (degrees == 90 || degrees == 270) {
    canvas.width = canvasCopy2.height;
    canvas.height = canvasCopy2.width;
  } else {
    canvas.width = canvasCopy2.width;
    canvas.height = canvasCopy2.height;
  }

  canvasContext.clearRect(0, 0, canvas.width, canvas.height);
  if (degrees == 90 || degrees == 270) {
    canvasContext.translate(canvasCopy2.height / 2, canvasCopy2.width / 2);
  } else {
    canvasContext.translate(canvasCopy2.width / 2, canvasCopy2.height / 2);
  }
  canvasContext.rotate(degrees * Math.PI / 180);
  canvasContext.drawImage(canvasCopy2, -canvasCopy2.width / 2, -canvasCopy2.height / 2);


  var dataURL = canvas.toDataURL();
  return dataURL;
} 

 /*
-------------------------------
-------UNNECESSARY CSS---------
-------------------------------
*/

@import url(http://fonts.googleapis.com/css?family=Lato);
 .container {
  margin: 0 auto;
  width: 400px;
  height: 400px;
  box-shadow: 1px 1px 1px 1px gray;
}
h3,
h4,
h5,
h6 {
  margin: 4px !important;
}
.container,
.container * {
  display: block;
  margin: 12px auto;
  font-family: 'Lato';
}
.header {
  background-color: #2196F3;
  padding: 12px;
  color: #fff;
}
.container input {
  width: 128px;
  height: 32px;
  cursor: pointer;
}
.container img {
  display: block;
  margin: 12px auto;
} 

 <div class="container">
  <div class="header">
    <h3>Choose a file</h3>
    <h6>and I will alert back to you the base64 string of it's resized version</h6>
  </div>
  <input type="file" id="input" />
  <hr>
  <h5>Image Preview:</h5>
  <img id="previewImg" src="" />

</div> 

First of all - The problem


I am developing a web application that enables the user to take a picture with their smartphone, tablet or just browse for a picture on their pc. I need to upload this file to my database, which is working perfectly IF the picture is small enough.

After experimenting a bit with certain photos, I found out that a smartphone takes a picture with a size of at least 1MB and this is way to big too upload to my database.

The uploading goes as following:
1. Convert the image to a Base64 encoded string.
2. Send the string in an array (contains string in pieces) to WebAPI
3. Join the strings into one and convert this into byte array.

I noticed that if a file is around 70-90kb, this would be the maximum size of a file that can be inserted in the database. The moment I have a file that is bigger then 100kb, the inserting fails.

So I am searching for a good resizing library to resize the picture that was chosen. I don't know if this is even possible, but everything has to be done client-side.

Technology


I am using Javascript/jQuery and AngularJS for the client side and VB.NET for my WebAPI. This is because I'm doing an internship and don't have another choice to use VB.NET.

But this has nothing to do with the issue, I just need to find a way to compress/resize/minimize the chosen file, so this can be uploaded to the database.

The upload is happening via the $http.post() from AngularJS.

If someone could advice a library, care to help a fellow programmer out with some basic example code? I mostly have trouble figuring out how to use a plugin or library, because I'm quite new to all this. And I would appreciate it if you guys could provide me with at least some information to get me on track.

Thanks in advance!

Sorry that I couldn't provide any code or something other, it's more an informative question than a coding problem. This might popup when I have a library that I can use. Also, if there are any remarks, I'll consider them, because I have a deadline and don't have much time left to start fixing small problems. Most of it works by now, except for that image problem.

解决方案

You can use the HTML5 Canvas element to blit your image on it and then resize it appropriately

You create a canvas on-the-fly and perform pixel operations on it - so don't worry it's not visible anywhere on the DOM - think of it like a virtual canvas

Here is a little script I've written a while ago(with some help from another S.O question which I don't really remember) - that allows you to do this - whilst keeping the aspect ratios of the image:

Arguments

  • You provide an image directly into it
  • You provide a maxWidth/maxHeight and it will preserve at least one of the 2
  • It allows you to also rotate the image by defining the degrees parameter(which would be really useful on mobile devices since different devices provide arbitrarily rotated images - you will find out about this the hard way soon if you are dealing with mobile devices)

Returns

  • It returns a Base64 string of the resized image

function resizeImg(img, maxWidth, maxHeight, degrees) {
  var imgWidth = img.width,
    imgHeight = img.height;

  var ratio = 1,
    ratio1 = 1,
    ratio2 = 1;
  ratio1 = maxWidth / imgWidth;
  ratio2 = maxHeight / imgHeight;

  // Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
  if (ratio1 < ratio2) {
    ratio = ratio1;
  } else {
    ratio = ratio2;
  }
  var canvas = document.createElement("canvas");
  var canvasContext = canvas.getContext("2d");
  var canvasCopy = document.createElement("canvas");
  var copyContext = canvasCopy.getContext("2d");
  var canvasCopy2 = document.createElement("canvas");
  var copyContext2 = canvasCopy2.getContext("2d");
  canvasCopy.width = imgWidth;
  canvasCopy.height = imgHeight;
  copyContext.drawImage(img, 0, 0);

  // init
  canvasCopy2.width = imgWidth;
  canvasCopy2.height = imgHeight;
  copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);


  var rounds = 1;
  var roundRatio = ratio * rounds;
  for (var i = 1; i <= rounds; i++) {


    // tmp
    canvasCopy.width = imgWidth * roundRatio / i;
    canvasCopy.height = imgHeight * roundRatio / i;

    copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);

    // copy back
    canvasCopy2.width = imgWidth * roundRatio / i;
    canvasCopy2.height = imgHeight * roundRatio / i;
    copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);

  } // end for

  canvas.width = imgWidth * roundRatio / rounds;
  canvas.height = imgHeight * roundRatio / rounds;
  canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);


  if (degrees == 90 || degrees == 270) {
    canvas.width = canvasCopy2.height;
    canvas.height = canvasCopy2.width;
  } else {
    canvas.width = canvasCopy2.width;
    canvas.height = canvasCopy2.height;
  }

  canvasContext.clearRect(0, 0, canvas.width, canvas.height);
  if (degrees == 90 || degrees == 270) {
    canvasContext.translate(canvasCopy2.height / 2, canvasCopy2.width / 2);
  } else {
    canvasContext.translate(canvasCopy2.width / 2, canvasCopy2.height / 2);
  }
  canvasContext.rotate(degrees * Math.PI / 180);
  canvasContext.drawImage(canvasCopy2, -canvasCopy2.width / 2, -canvasCopy2.height / 2);


  var dataURL = canvas.toDataURL();
  return dataURL;
}


And here's a working code snippet that allows you to upload from your filesystem and resize on the fly:

/*
-------------------------------
-------HANDLE FILE UPLOAD------
-------------------------------
*/

var input = document.getElementById('input');
input.addEventListener('change', handleFiles);

function handleFiles(e) {
  var img = new Image;
  img.src = URL.createObjectURL(e.target.files[0]);
  img.onload = function() {
    var base64String = resizeImg(img, 300, 300, 0); //HERE IS WHERE THE FUNCTION RESIZE IS CALLED!!!!
    alert(base64String);
    document.getElementById('previewImg').src = base64String;
  }
}



/*
-------------------------------
-------RESIZING FUNCTION-------
-------------------------------
*/


function resizeImg(img, maxWidth, maxHeight, degrees) {
  var imgWidth = img.width,
    imgHeight = img.height;

  var ratio = 1,
    ratio1 = 1,
    ratio2 = 1;
  ratio1 = maxWidth / imgWidth;
  ratio2 = maxHeight / imgHeight;

  // Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
  if (ratio1 < ratio2) {
    ratio = ratio1;
  } else {
    ratio = ratio2;
  }
  var canvas = document.createElement("canvas");
  var canvasContext = canvas.getContext("2d");
  var canvasCopy = document.createElement("canvas");
  var copyContext = canvasCopy.getContext("2d");
  var canvasCopy2 = document.createElement("canvas");
  var copyContext2 = canvasCopy2.getContext("2d");
  canvasCopy.width = imgWidth;
  canvasCopy.height = imgHeight;
  copyContext.drawImage(img, 0, 0);

  // init
  canvasCopy2.width = imgWidth;
  canvasCopy2.height = imgHeight;
  copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);


  var rounds = 1;
  var roundRatio = ratio * rounds;
  for (var i = 1; i <= rounds; i++) {


    // tmp
    canvasCopy.width = imgWidth * roundRatio / i;
    canvasCopy.height = imgHeight * roundRatio / i;

    copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);

    // copy back
    canvasCopy2.width = imgWidth * roundRatio / i;
    canvasCopy2.height = imgHeight * roundRatio / i;
    copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);

  } // end for

  canvas.width = imgWidth * roundRatio / rounds;
  canvas.height = imgHeight * roundRatio / rounds;
  canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);


  if (degrees == 90 || degrees == 270) {
    canvas.width = canvasCopy2.height;
    canvas.height = canvasCopy2.width;
  } else {
    canvas.width = canvasCopy2.width;
    canvas.height = canvasCopy2.height;
  }

  canvasContext.clearRect(0, 0, canvas.width, canvas.height);
  if (degrees == 90 || degrees == 270) {
    canvasContext.translate(canvasCopy2.height / 2, canvasCopy2.width / 2);
  } else {
    canvasContext.translate(canvasCopy2.width / 2, canvasCopy2.height / 2);
  }
  canvasContext.rotate(degrees * Math.PI / 180);
  canvasContext.drawImage(canvasCopy2, -canvasCopy2.width / 2, -canvasCopy2.height / 2);


  var dataURL = canvas.toDataURL();
  return dataURL;
}

/*
-------------------------------
-------UNNECESSARY CSS---------
-------------------------------
*/

@import url(http://fonts.googleapis.com/css?family=Lato);
 .container {
  margin: 0 auto;
  width: 400px;
  height: 400px;
  box-shadow: 1px 1px 1px 1px gray;
}
h3,
h4,
h5,
h6 {
  margin: 4px !important;
}
.container,
.container * {
  display: block;
  margin: 12px auto;
  font-family: 'Lato';
}
.header {
  background-color: #2196F3;
  padding: 12px;
  color: #fff;
}
.container input {
  width: 128px;
  height: 32px;
  cursor: pointer;
}
.container img {
  display: block;
  margin: 12px auto;
}

<div class="container">
  <div class="header">
    <h3>Choose a file</h3>
    <h6>and I will alert back to you the base64 string of it's resized version</h6>
  </div>
  <input type="file" id="input" />
  <hr>
  <h5>Image Preview:</h5>
  <img id="previewImg" src="" />

</div>

这篇关于调整图像大小,需要一个好的库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆