이 글은 주로 H5 이미지 압축과 업로드 예시를 자세하게 소개하고 있습니다. 관심 있는 친구들이 참고해 보세요.
프런트엔드에서 이미지를 압축할 수 있는지 문의해 봤습니다. 일부 이미지는 크기가 너무 커서 서버로 전송한 후 압축하는 데 속도가 너무 느립니다. 의식적으로 이렇게 놀아본 적은 없었는데 아침에 사장님이 지후 링크를 보내주셨는데 보니 선배님들이 이미 캔버스로 구현해놓으셨더라구요. 그리고 즉시 작업을 시작했습니다)! .
캔버스 압축
은 github에서 기성 라이브러리를 사용합니다: https://github.com/stomita/ios-imagefile-megapixel. 위대한 신 stomita를 숭배해야 합니다. 일반적인 아이디어는 이미지를 샘플링하여 캔버스에 표시한 다음 canvas.toDataURL 메서드를 사용하여 base64 문자열을 얻어 압축하는 것입니다. 예를 들어 입력 요소가 변경 이벤트를 트리거한 후 내부의 파일을 읽고 작동합니다.
var fileInput = document.getElementById('fileInput'); fileInput.onchange = function() { var file = fileInput.files[0]; // 创建一个压缩对象,该构造函数接收file或者blob。 var mpImg = new MegaPixImage(file); // render方法的maxWith,maxHeight,以及quality都决定了压缩图片的质量 var resImg = document.getElementById('resultImage'); mpImg.render(resImg, { maxWidth: 300, maxHeight: 300, quality: 0.5 }); }; 压缩完成会得到
다음과 유사한 그림:
data:image/jpeg 이 형식은 많이 사용되었으며 많은 스타일이 있습니다. 내부의 배경 이미지는 다음과 같습니다.
여기에 있는 resImg는 미리보기 이미지로, 미리보기가 필요하지 않지만 압축을 위해 img를 생성하면 됩니다(document.createElement("img")). tagName 속성이 하나 적습니다. 소스 코드를 수정하거나 이 속성을 직접 추가할 수 있습니다. 소스 코드는 tagName을 기준으로 판단됩니다. 존재하지 않으면 다음과 같은 오류가 보고됩니다.
MegaPixImage.prototype.render = function (target, options, callback) { //.... target.tagName = target.tagName || "IMG"; //加上这一句 var tagName = target.tagName.toLowerCase(); if (tagName === 'img') { target.src = renderImageToDataURL(this.srcImage, opt, doSquash); } else if (tagName === 'canvas') { renderImageToCanvas(this.srcImage, target, opt, doSquash); } if (typeof this.onrender === 'function') { this.onrender(target); } if (callback) { callback(); } if (this.blob) { this.blob = null; URL.revokeObjectURL(this.srcImage.src); } };
또한 이 작업은 시간이 많이 걸리는 작업이므로 압축할 수 없습니다. 직접 호출해야 합니다. 그렇지 않으면 이전 그림이 압축되지 않고 나중 그림으로 들어갑니다.
fileSelected: function () { var files = $("#fileImage")[0].files; var count = files.length; console.log("共有" + count + "个文件"); for (var i = 0; i < count; i++) {var item = files[i]; console.log("原图片大小", item.size); if (item.size > 1024 * 1024 * 2) { console.log("图片大于2M,开始进行压缩..."); (function(img) { var mpImg = new MegaPixImage(img); var resImg = document.createElement("img"); resImg.file = img; mpImg.render(resImg, { maxWidth: 500, maxHeight: 500, quality: 1 }, function() { //do some thing }); })(item); } core.previewImage(item); } },
업로드 처리
1. base64 문자열 직접 게시
uploadBase64str: function (base64Str) { var formdata = new FormData(); formdata.append("base64str", base64Str); var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", function (e) { var percentComplete = Math.round(e.loaded * 100 / e.total); para.onProgress(percentComplete.toString() + '%'); }); xhr.addEventListener("load", function (e) { para.uploadComplete(xhr.responseText); }); xhr.addEventListener("error", function (e) { para.uploadError(e); }); xhr.open("post", para.base64strUrl, true); xhr.send(formdata); },
예를 들어 여기서 base64strUrl은 /home/MUploadImgBase64Str이고 MVC 컨트롤러 메서드는 다음과 같습니다.
르레에몇 개의 M 사진을 수십 또는 수백 킬로바이트로 압축할 수 있습니까? 물론 너비, 높이 및 품질을 너무 작게 설정하면 사진이 매우 왜곡됩니다. 이 문자열을 얻는 방법은 무엇입니까? 두 가지 방법이 있습니다. 하나는 src를 직접 읽는 것입니다:
var base641 = resImg.src;
다른 하나는 캔버스 변환을 사용하는 것입니다:
[HttpPost] public ActionResult MUploadImgBase64Str(string base64str) { try { var imgData = base64str.Split(',')[1]; //过滤特殊字符即可 string dummyData = imgData.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+"); if (dummyData.Length % 4 > 0) { dummyData = dummyData.PadRight(dummyData.Length + 4 - dummyData.Length % 4, '='); } byte[] byteArray = Convert.FromBase64String(dummyData); using (System.IO.MemoryStream ms = new System.IO.MemoryStream(byteArray)) { var img = System.Drawing.Image.FromStream(ms); var path = "~/Content/UploadFiles/mobile/"; var uploadpath = Server.MapPath(path); if (!Directory.Exists(uploadpath)) { Directory.CreateDirectory(uploadpath); } var saveName = uploadpath + “stoneniqiu” + ".jpg"; img.Save(saveName); return Json(saveName); } } catch (Exception e) { return Json(e.Message); } }
동일한 그림, 둘 다에서 얻은 문자 끈 크기가 다르지만 화질 차이는 잘 모르겠습니다.
예를 들어 2M 이미지의 경우 getBase64Image 메서드를 통해 읽은 문자열 크기는 64k에 불과하지만 src에서 직접 읽은 크기는 270k이므로 결과 이미지는 더 작습니다. 다음은 원본 이미지(2.2M), base64(48k), src(202k)에 해당하는 이미지입니다.
getBase64Image는 캔버스의 toDataURL을 통해 더 작은 base64 문자열을 얻습니다.
2. 프런트 엔드에서 blob 개체를 변환한 다음 백엔드에 게시할 수도 있습니다.
function getBase64Image(img) { var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, img.width, img.height); var dataURL = canvas.toDataURL("image/jpeg"); return dataURL; // return dataURL.replace("data:image/png;base64,", ""); } var base64 = getBase64Image(resImg);
3. 압축되지 않은 경우 양식 데이터에 직접 설치하고 백엔드로 보냅니다. .
function dataURItoBlob(dataUrl) { var byteString = atob(dataUrl.split(',')[1]); var ab = new ArrayBuffer(byteString.length); var ia = new Uint8Array(ab); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ab], { type: 'image/jpeg' }); }
위 내용은 모두의 학습에 도움이 되기를 바랍니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 주목해주세요!
관련 권장사항:
HTML5 모바일 개발을 통해 이미지 압축 및 업로드 기능 구현
위 내용은 H5는 이미지 압축 및 업로드를 실현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!