تنبع هذه المشكلة من حقيقة أنه عند تحميل ملفات الصور، يحدد حجم الخلفية بـ 2 ميجابايت، ولكن عند تشغيل الكاميرا لالتقاط الصور، يتجاوز حجمها 2 ميجابايت كل دقيقة، وذلك حتى لا يؤثر على تجربة المستخدم والمتطلبات الوظيفية تحتاج الواجهة الأمامية إلى ضغط الحجم ثم تحميله خلف الكواليس.
تحليل الفكرةبعد البحث في الكثير من المعلومات، وجدت أن القماش وحده يمكنه ضغط الصور.
المبدأ تقريبًا كما يلي: 1. قم أولاً بتحويل ملف الصورة إلى عنوان URL الأساسي 2. قم بإنشاء علامة صورة لتلقي الملف والحصول على عرض الصورة وارتفاعها وتناسبها. 3. قم بإنشاء لوحة قماشية وضبط حجم اللوحة القماشية. 4. ارسم الصورة على القماش. 5. قم بضغط اللوحة القماشية واحصل على عنوان URL الأساسي الجديد 6. قم بتحويل عنوان URL الأساسي مرة أخرى إلى ملف.
وظيفة الفرضية تحويل ملف الملف إلى base64/*** @param {binary filestream} file * @param {callback function, return base64} fn */functionchangeFileToBaseURL(file,fn){ // إنشاء كائن ملف القراءة var fileReader = new FileReader() //; إذا لم يتم تعريف الملف، فسيتم إرجاعه فارغًا if(file == uncategorized) return fn(null); fileReader.onload = function(){ // اقرأ base64 var imgBase64Data = this.result;تحويل Base64 إلى دفق الملف
/** * تحويل base64 إلى ملف * @param {baseURL} dataurl * @param {file name} filename * @return {file ثنائي دفق}*/function dataURLtoFile(dataurl, filename) { var arr = dataurl.split(' , ')، mime = arr[0].match(/:(.*?);/)[1]، bstr = atob(arr[1])، n = bstr.length, u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, {type:mime});طريقة الضغط
/*** صورة مضغوطة من القماش* @param {parameter obj} param * @param {file ثنائي دفق} param.file مطلوب* @param {target Pressure size} param.targetSize لا يمرر المهمة الأولية -1* @param {output عرض الصورة} لا يمرر param.width قيمة المهمة الأولية -1، ولا يمرر الارتفاع للقياس التناسبي* @param {اسم صورة الإخراج} لا يمرر param.fileName صورة المهمة الأولية* @param {درجة الصورة المضغوطة } لا تتجاوز param.quality قيمة التعيين الأولية البالغة 0.92. نطاق القيمة 0 ~ 1* @param {callback function} param.succ مطلوب */function pressImg(param){ // إذا لم تكن هناك وظيفة رد اتصال، فلن يتم تنفيذها if(param && param.succ){ //If لم يتم تعريف الملف، قم بإرجاعه فارغًا if(param.file == unified) return param.succ(null); // إرفاق قيمة أولية بالمعلمة param.targetSize = param.hasOwnProperty(targetSize)? param.targetSize : -1; param.width = param.hasOwnProperty(width) ? param.width : -1; param.hasOwnProperty(fileName) ? الجودة) ?param.quality : 0.92; var _this = this; = param.file.type; // console.log(fileType) //image/jpeg if(fileType.indexOf(image) == -1){ console.log('الرجاء تحديد ملف صورة ^_^'); return param.succ(null); } // إذا كان الحجم الحالي أصغر من الحجم المستهدف، فسيتم إخراجه مباشرة var size = param.file.size; ); } // اقرأ ملف الملف والنتيجة هي base64 ChangeFileToBaseURL(param.file,function(base64){ if(base64){ var image = new Image(); image.src = base64; image.onload = function(){ // Get نسبة العرض إلى الارتفاع varscale = this.width / this.height // console.log(scale) // إنشاء لوحة قماشية var Canvas = document.createElement('canvas'); // احصل على السياق var context = Canvas.getContext('2d'); // احصل على عرض الصورة المضغوطة. width : param.width; // احصل على ارتفاع الصورة المضغوطة. إذا كان العرض -1، فإن ارتفاع الصورة الأصلية الافتراضي هو Canvas.height = param.width == -1? parseInt(param.width /scale); // ارسم الصورة على القماش context.drawImage(image, 0, 0, Canvas.width, Canvas.height); // ضغط الصورة واحصل على قاعدة 64Url جديدة var newImageData = Canvas . toDataURL(fileType,param.quality); // تحويل base64 إلى دفق ملف var resultFile = dataURLtoFile(newImageData,param.fileName); // الحكم إذا كان حجم الهدف محدودًا وكان حجم الصورة المضغوطة أكبر من الحجم المستهدف، فسيظهر خطأ if(param.targetSize != -1 && param.targetSize < resultFile.size ){ console .log(حجم تحميل الصورة كبير جدًا، يرجى إعادة التحميل^_^); // إرجاع دفق الملف param.succ(resultFile);استخدام الطريقة
حجم الملف بالبايت، لذلك نحن بحاجة إلى تحويل الحجم المطلوب إلى بايت. 1 بايت هو 1 بايت هو 1B، 1KB = 1024B، 1MB = 1024 * 1024B
<نوع الإدخال=معرف الملف=فئة الملفImg=ملفImg/>
// احصل على تحميل ملف الصورة url$(#fileImg).on('change',function(){ pressImg({ file:this.files[0], targetSize:2 * 1024 * 1024, الجودة: 0.5, العرض: 600 , succ:function(resultFile){ // إذا لم يكن فارغًا، يكون الضغط ناجحًا if(resultFile){ //TODO } } })});ملخص المشكلة مستوى ضغط الصورة
ليس من السهل تحديد درجة ضغط الصورة، لذا يمكنك تجربتها عدة مرات وتعديلها وفقًا لمتطلبات الطالب. يمكن أن يؤدي تغيير حجم الصورة المستهدفة ودقتها إلى تغيير درجة ضغط الصورة.
في الأصل كنت أرغب في القيام بعملية متكررة لضغط الصور حتى يفي حجم الصورة بالتوقعات.اكتشفت لاحقا
لأنه عندما يستدعي نظام iOS كاميرا النظام لالتقاط الصور، يتم تدويرها بمقدار 90 درجة عكس اتجاه عقارب الساعة. بعد أن قمت بضغط الصورة وإرسالها إلى الخلفية، وجدت أن اتجاه التصوير لمعلومات exif الخاصة بالصورة قد فقد، مما تسبب في تدوير الصور التي تم تحميلها بواسطة iOS بمقدار 90 درجة عكس اتجاه عقارب الساعة. لم يلاحظ Android هذه المشكلة أبدًا.
في الوقت الحاضر، هناك بعض الشكوك حول فقدانه عندما تم تحويل Base64 إلى ملف ملف. سيتم توفير تعليمات إضافية هنا بعد التحقق.
@version1.0-2019-8-2-إنشاء "استخدام اللوحة القماشية لضغط حجم الصورة"
©burning_Yun Qiqi
ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.