ब्राउज़र में जावास्क्रिप्ट के माध्यम से एक छवि कैसे संपीड़ित करें?


91

टी एल; डॉ;

क्या अपलोड करने से पहले एक छवि (अधिकतर jpeg, png और gif) को सीधे ब्राउज़र-साइड पर संपीड़ित करने का एक तरीका है? मुझे पूरा यकीन है कि जावास्क्रिप्ट ऐसा कर सकती है, लेकिन मुझे इसे हासिल करने का कोई रास्ता नहीं मिल रहा है।


यहां पूरा परिदृश्य मैं लागू करना चाहता हूं:

  • उपयोगकर्ता मेरी वेबसाइट पर जाता है, और एक input type="file"तत्व के माध्यम से एक छवि चुनता है,
  • इस छवि को जावास्क्रिप्ट के माध्यम से पुनर्प्राप्त किया जाता है, हम कुछ सत्यापन करते हैं जैसे कि सही फ़ाइल प्रारूप, अधिकतम फ़ाइल आकार आदि।
  • यदि प्रत्येक चीज़ ठीक है, तो छवि का पूर्वावलोकन पृष्ठ पर प्रदर्शित होता है,
  • उपयोगकर्ता कुछ बुनियादी ऑपरेशन कर सकता है जैसे कि छवि को 90 ° / -90 ° से घुमाएं, इसे पूर्व-निर्धारित अनुपात के अनुसार क्रॉप करें, या उपयोगकर्ता दूसरी छवि अपलोड कर सकता है और चरण 1 पर वापस आ सकता है,
  • जब उपयोगकर्ता संतुष्ट हो जाता है, तो संपादित की गई छवि को तब संपीड़ित किया जाता है और स्थानीय रूप से "सहेजा" जाता है (फ़ाइल में सहेजा नहीं जाता है, लेकिन ब्राउज़र मेमोरी / पेज में, -)
  • उपयोगकर्ता नाम, आयु आदि जैसे डेटा के साथ एक फॉर्म भरता है,
  • उपयोगकर्ता "फिनिश" बटन पर क्लिक करें, फिर डेटा + संपीड़ित छवि वाला फॉर्म सर्वर (AJAX के बिना) के लिए भेजा जाता है,

अंतिम चरण तक की पूरी प्रक्रिया क्लाइंट की तरफ होनी चाहिए, और नवीनतम क्रोम और फ़ायरफ़ॉक्स, सफारी 5+ और आईई 8+ पर संगत होनी चाहिए । यदि संभव हो, तो केवल जावास्क्रिप्ट का उपयोग किया जाना चाहिए (लेकिन मुझे पूरा यकीन है कि यह संभव नहीं है)।

मैंने अभी कुछ भी कोड नहीं किया है, लेकिन मैंने इसके बारे में पहले ही सोच लिया है। फ़ाइल एपीआई के माध्यम से स्थानीय रूप से फ़ाइल पढ़ना संभव है , कैनवस तत्व का उपयोग करके छवि पूर्वावलोकन और संपादन किया जा सकता है , लेकिन मुझे छवि संपीड़न भाग करने का कोई तरीका नहीं मिल सकता है

Html5please.com और caniuse.com के अनुसार , उन ब्राउज़र का समर्थन करना काफी कठिन है (IE के लिए धन्यवाद), लेकिन FlashCanvas और FileReader जैसे पॉलीफिल का उपयोग करके किया जा सकता है ।

दरअसल, लक्ष्य फ़ाइल आकार को कम करना है, इसलिए मैं छवि संपीड़न को एक समाधान के रूप में देखता हूं। लेकिन, मुझे पता है कि अपलोड की गई छवियां मेरी वेबसाइट पर, हर बार उसी स्थान पर प्रदर्शित होने वाली हैं, और मुझे इस प्रदर्शन क्षेत्र का आयाम पता है (उदाहरण। 200x400)। इसलिए, मैं उन आयामों को फिट करने के लिए छवि का आकार बदल सकता हूं, इस प्रकार फ़ाइल का आकार कम कर सकता हूं। मुझे नहीं पता कि इस तकनीक के लिए संपीड़न अनुपात क्या होगा।

तुम क्या सोचते हो ? क्या आपके पास मुझे बताने की कोई सलाह है? क्या आप जावास्क्रिप्ट में एक छवि ब्राउज़र-साइड को संपीड़ित करने का कोई तरीका जानते हैं? आपके उत्तर के लिए धन्यवाद।

जवाबों:


164

संक्षेप में:

  • HTML5 FileReader API को .readAsArrayBuffer का उपयोग करके फ़ाइलें पढ़ें
  • फ़ाइल डेटा के साथ एक Blob बनाएँ और उसका url window.URL.createObjectURL (blob) के साथ प्राप्त करें
  • नया इमेज एलिमेंट बनाएं और सेट करें यह src फाइल ब्लॉब यूआरएल के लिए है
  • छवि को कैनवास पर भेजें। कैनवास का आकार वांछित आउटपुट आकार पर सेट है
  • कैनवास के माध्यम से कैनवास से स्केल-डाउन डेटा वापस प्राप्त करें। "चित्र / jpeg", 0.7) (अपना स्वयं का आउटपुट स्वरूप और गुणवत्ता सेट करें)
  • नए छिपे हुए इनपुट को मूल रूप में संलग्न करें और डेटारी छवियों को मूल रूप से सामान्य पाठ के रूप में स्थानांतरित करें
  • बैकएंड पर, डेटारी पढ़ें, बेस 64 से डीकोड करें, और इसे सहेजें

स्रोत: कोड


1
आपका बहुत बहुत धन्यवाद ! यह वही है जिसे मैं देख रहा था। क्या आप जानते हैं कि इस तकनीक के साथ संपीड़न अनुपात कितना अच्छा है?
pomeh

2
@ निचलोलकायरकाइड्स मैं पुष्टि कर सकता हूं कि canvas.toDataURL("image/jpeg",0.7)यह प्रभावी रूप से संपीड़ित करता है, यह जेपीईजी को गुणवत्ता 70 (डिफ़ॉल्ट रूप से, गुणवत्ता 100 के विपरीत) बचाता है।
user1111929

4
@ निकोलस क्यारीकाइड्स, यह बनाने के लिए अच्छा अंतर नहीं है। अधिकांश कोडक दोषरहित नहीं होते हैं, इसलिए वे आपकी "डाउनस्क्कालिंग" परिभाषा में फिट होंगे (यानी आप 100 पर वापस नहीं आ सकते)।
बिलीबोबोनेट

5
डाउनस्कालिंग से तात्पर्य ऊंचाई और चौड़ाई के संदर्भ में छोटे आकार की छवियां बनाने से है। यह वास्तव में संपीड़न है। यह हानिपूर्ण संपीड़न लेकिन निश्चित रूप से संपीड़न है। यह पिक्सल्स को नीचा नहीं कर रहा है, यह कुछ पिक्सल्स को एक ही रंग के होने का संकेत देता है ताकि कम से कम बिट्स में कंप्रेशन उन रंगों को हिट कर सके। जेपीईजी ने वैसे भी पिक्सल के लिए संपीड़न में निर्मित किया है, लेकिन हानिपूर्ण मोड में यह कहता है कि कुछ रंगों को एक ही रंग कहा जा सकता है। यह अभी भी संपीड़न है। ग्राफिक्स के संबंध में डाउनस्कलिंग आमतौर पर वास्तविक आकार में परिवर्तन को संदर्भित करता है।
ताताराइज करें

3
मैं सिर्फ यह कहना चाहता हूं: URL.createObjectUrl()फ़ाइल को एक बूँद में बदल दिए बिना सीधे जा सकते हैं ; फ़ाइल एक बूँद के रूप में गिना जाता है।
नरकोल ११

20

मुझे अन्य उत्तरों में से दो चीजें गायब हैं:

  • canvas.toBlob(जब उपलब्ध हो) की तुलना में अधिक निष्पादन योग्य है canvas.toDataURL, और यह भी async है।
  • फ़ाइल -> छवि -> कैनवास -> फ़ाइल रूपांतरण EXIF ​​डेटा खो देता है; विशेष रूप से, छवि रोटेशन के बारे में डेटा आमतौर पर आधुनिक फोन / टैबलेट द्वारा निर्धारित किया जाता है।

निम्नलिखित स्क्रिप्ट दोनों बिंदुओं से संबंधित है:

// From https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob, needed for Safari:
if (!HTMLCanvasElement.prototype.toBlob) {
    Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
        value: function(callback, type, quality) {

            var binStr = atob(this.toDataURL(type, quality).split(',')[1]),
                len = binStr.length,
                arr = new Uint8Array(len);

            for (var i = 0; i < len; i++) {
                arr[i] = binStr.charCodeAt(i);
            }

            callback(new Blob([arr], {type: type || 'image/png'}));
        }
    });
}

window.URL = window.URL || window.webkitURL;

// Modified from https://stackoverflow.com/a/32490603, cc by-sa 3.0
// -2 = not jpeg, -1 = no data, 1..8 = orientations
function getExifOrientation(file, callback) {
    // Suggestion from http://code.flickr.net/2012/06/01/parsing-exif-client-side-using-javascript-2/:
    if (file.slice) {
        file = file.slice(0, 131072);
    } else if (file.webkitSlice) {
        file = file.webkitSlice(0, 131072);
    }

    var reader = new FileReader();
    reader.onload = function(e) {
        var view = new DataView(e.target.result);
        if (view.getUint16(0, false) != 0xFFD8) {
            callback(-2);
            return;
        }
        var length = view.byteLength, offset = 2;
        while (offset < length) {
            var marker = view.getUint16(offset, false);
            offset += 2;
            if (marker == 0xFFE1) {
                if (view.getUint32(offset += 2, false) != 0x45786966) {
                    callback(-1);
                    return;
                }
                var little = view.getUint16(offset += 6, false) == 0x4949;
                offset += view.getUint32(offset + 4, little);
                var tags = view.getUint16(offset, little);
                offset += 2;
                for (var i = 0; i < tags; i++)
                    if (view.getUint16(offset + (i * 12), little) == 0x0112) {
                        callback(view.getUint16(offset + (i * 12) + 8, little));
                        return;
                    }
            }
            else if ((marker & 0xFF00) != 0xFF00) break;
            else offset += view.getUint16(offset, false);
        }
        callback(-1);
    };
    reader.readAsArrayBuffer(file);
}

// Derived from https://stackoverflow.com/a/40867559, cc by-sa
function imgToCanvasWithOrientation(img, rawWidth, rawHeight, orientation) {
    var canvas = document.createElement('canvas');
    if (orientation > 4) {
        canvas.width = rawHeight;
        canvas.height = rawWidth;
    } else {
        canvas.width = rawWidth;
        canvas.height = rawHeight;
    }

    if (orientation > 1) {
        console.log("EXIF orientation = " + orientation + ", rotating picture");
    }

    var ctx = canvas.getContext('2d');
    switch (orientation) {
        case 2: ctx.transform(-1, 0, 0, 1, rawWidth, 0); break;
        case 3: ctx.transform(-1, 0, 0, -1, rawWidth, rawHeight); break;
        case 4: ctx.transform(1, 0, 0, -1, 0, rawHeight); break;
        case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
        case 6: ctx.transform(0, 1, -1, 0, rawHeight, 0); break;
        case 7: ctx.transform(0, -1, -1, 0, rawHeight, rawWidth); break;
        case 8: ctx.transform(0, -1, 1, 0, 0, rawWidth); break;
    }
    ctx.drawImage(img, 0, 0, rawWidth, rawHeight);
    return canvas;
}

function reduceFileSize(file, acceptFileSize, maxWidth, maxHeight, quality, callback) {
    if (file.size <= acceptFileSize) {
        callback(file);
        return;
    }
    var img = new Image();
    img.onerror = function() {
        URL.revokeObjectURL(this.src);
        callback(file);
    };
    img.onload = function() {
        URL.revokeObjectURL(this.src);
        getExifOrientation(file, function(orientation) {
            var w = img.width, h = img.height;
            var scale = (orientation > 4 ?
                Math.min(maxHeight / w, maxWidth / h, 1) :
                Math.min(maxWidth / w, maxHeight / h, 1));
            h = Math.round(h * scale);
            w = Math.round(w * scale);

            var canvas = imgToCanvasWithOrientation(img, w, h, orientation);
            canvas.toBlob(function(blob) {
                console.log("Resized image to " + w + "x" + h + ", " + (blob.size >> 10) + "kB");
                callback(blob);
            }, 'image/jpeg', quality);
        });
    };
    img.src = URL.createObjectURL(file);
}

उदाहरण उपयोग:

inputfile.onchange = function() {
    // If file size > 500kB, resize such that width <= 1000, quality = 0.9
    reduceFileSize(this.files[0], 500*1024, 1000, Infinity, 0.9, blob => {
        let body = new FormData();
        body.set('file', blob, blob.name || "file.jpg");
        fetch('/upload-image', {method: 'POST', body}).then(...);
    });
};

ToBlob ने मेरे लिए ट्रिक बनाई, एक फाइल बनाई और सर्वर में $ _FILES एरे में रिजेक्ट किया। धन्यवाद!
रिकार्डो रूइज रोमेरो

अच्छा लग रहा है! लेकिन क्या यह सभी ब्राउज़र, वेब और मोबाइल पर काम करेगा? (आइई को नजरअंदाज करें)
गर्विट जैन

14

@PychoWoods का जवाब अच्छा है। मैं अपने समाधान की पेशकश करना चाहूंगा। यह जावास्क्रिप्ट फ़ंक्शन एक छवि डेटा URL और एक चौड़ाई लेता है, इसे नई चौड़ाई पर ले जाता है, और एक नया डेटा URL देता है।

// Take an image URL, downscale it to the given width, and return a new image URL.
function downscaleImage(dataUrl, newWidth, imageType, imageArguments) {
    "use strict";
    var image, oldWidth, oldHeight, newHeight, canvas, ctx, newDataUrl;

    // Provide default values
    imageType = imageType || "image/jpeg";
    imageArguments = imageArguments || 0.7;

    // Create a temporary image so that we can compute the height of the downscaled image.
    image = new Image();
    image.src = dataUrl;
    oldWidth = image.width;
    oldHeight = image.height;
    newHeight = Math.floor(oldHeight / oldWidth * newWidth)

    // Create a temporary canvas to draw the downscaled image on.
    canvas = document.createElement("canvas");
    canvas.width = newWidth;
    canvas.height = newHeight;

    // Draw the downscaled image on the canvas and return the new data URL.
    ctx = canvas.getContext("2d");
    ctx.drawImage(image, 0, 0, newWidth, newHeight);
    newDataUrl = canvas.toDataURL(imageType, imageArguments);
    return newDataUrl;
}

इस कोड का उपयोग कहीं भी किया जा सकता है जहां आपके पास एक डेटा URL है और एक डाउन-डाउन छवि के लिए एक डेटा URL चाहते हैं।


कृपया, क्या आप मुझे इस उदाहरण के बारे में अधिक जानकारी दे सकते हैं कि फ़ंक्शन कैसे कॉल करें और परिणाम कैसे लौटाएं?
१३:

यहाँ एक उदाहरण है: danielsadvt.info/Html/scaleimage.html पृष्ठ का स्रोत पढ़ने के लिए सुनिश्चित करें कि यह कैसे काम करता है।
विवियन नदी

1
web.archive.org/web/20171226190510/danielsadvt.info/Html/… अन्य लोगों के लिए, जो @DanielAllenLangdon द्वारा लिंक का प्रस्ताव पढ़ना चाहते हैं
सिडरिक अर्नोल्ड

एक सिर के रूप में, कभी-कभी image. उपलब्धता / ऊंचाई 0 पर वापस आ जाएगी क्योंकि यह लोड नहीं हुआ है। इसके साथ सही छवि प्राप्त करने और ऊंचाई के लिए आपको इसे एक async फ़ंक्शन में परिवर्तित करने और image.onload को सुनने की आवश्यकता हो सकती है।
मैट पोप

9

आप छवि-रूपांतरण पर एक नज़र डाल सकते हैं , इसे यहाँ आज़माएँ -> डेमो पेज

यहाँ छवि विवरण दर्ज करें


1
कृपया लिंक किए गए संसाधनों के बारे में कुछ जानकारी जोड़ें
SanSolo

यह जवाब एकदम सही है!
djcaesar9114

डेमो पेज लिंक टूट गया है। आप यहां परीक्षण कर सकते हैं: Demo.wangyulue.com/image-conversion
gabrielstuff

4

मेरे पास downscaleImage()@ daniel-allen-langdon द्वारा ऊपर पोस्ट किए गए फ़ंक्शन के साथ एक समस्या थी image.widthऔर image.heightगुण तुरंत उपलब्ध नहीं हैं क्योंकि छवि लोड अतुल्यकालिक है

कृपया नीचे टाइप किए गए टाइपस्क्रिप्ट उदाहरण देखें जो इसे ध्यान में रखते हैं, asyncफ़ंक्शंस का उपयोग करता है, और केवल चौड़ाई के बजाय सबसे लंबे आयाम के आधार पर छवि का आकार बदलता है

function getImage(dataUrl: string): Promise<HTMLImageElement> 
{
    return new Promise((resolve, reject) => {
        const image = new Image();
        image.src = dataUrl;
        image.onload = () => {
            resolve(image);
        };
        image.onerror = (el: any, err: ErrorEvent) => {
            reject(err.error);
        };
    });
}

export async function downscaleImage(
        dataUrl: string,  
        imageType: string,  // e.g. 'image/jpeg'
        resolution: number,  // max width/height in pixels
        quality: number   // e.g. 0.9 = 90% quality
    ): Promise<string> {

    // Create a temporary image so that we can compute the height of the image.
    const image = await getImage(dataUrl);
    const oldWidth = image.naturalWidth;
    const oldHeight = image.naturalHeight;
    console.log('dims', oldWidth, oldHeight);

    const longestDimension = oldWidth > oldHeight ? 'width' : 'height';
    const currentRes = longestDimension == 'width' ? oldWidth : oldHeight;
    console.log('longest dim', longestDimension, currentRes);

    if (currentRes > resolution) {
        console.log('need to resize...');

        // Calculate new dimensions
        const newSize = longestDimension == 'width'
            ? Math.floor(oldHeight / oldWidth * resolution)
            : Math.floor(oldWidth / oldHeight * resolution);
        const newWidth = longestDimension == 'width' ? resolution : newSize;
        const newHeight = longestDimension == 'height' ? resolution : newSize;
        console.log('new width / height', newWidth, newHeight);

        // Create a temporary canvas to draw the downscaled image on.
        const canvas = document.createElement('canvas');
        canvas.width = newWidth;
        canvas.height = newHeight;

        // Draw the downscaled image on the canvas and return the new data URL.
        const ctx = canvas.getContext('2d')!;
        ctx.drawImage(image, 0, 0, newWidth, newHeight);
        const newDataUrl = canvas.toDataURL(imageType, quality);
        return newDataUrl;
    }
    else {
        return dataUrl;
    }

}

मैं का विवरण जोड़ना होगा quality, resolutionऔर imageType(इस का प्रारूप)
बाराबास

3

संपादित करें: इस उत्तर पर श्री मी टिप्पणी के अनुसार, ऐसा लगता है कि संपीड़न अब JPG / WebP स्वरूपों के लिए उपलब्ध है (देखें https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement-toDataURL ) ।

जहां तक ​​मुझे पता है, आप कैनवस का उपयोग करके छवियों को संपीड़ित नहीं कर सकते हैं, इसके बजाय, आप इसे आकार बदल सकते हैं। कैनवास का उपयोग करना ।toDataURL आपको उपयोग करने के लिए संपीड़न अनुपात का चयन नहीं करने देगा। आप कैनमीज पर एक नज़र डाल सकते हैं, जो आप चाहते हैं: https://github.com/nfroidure/CanImage/blob/master/chrome/canimage/content/canimage.js

वास्तव में, यह अक्सर आकार को कम करने के लिए केवल छवि का आकार बदलने के लिए पर्याप्त होता है लेकिन यदि आप आगे जाना चाहते हैं, तो आपको छवि डेटा वाले बफर को प्राप्त करने के लिए नए पेश किए गए विधि file.readAsArrayBuffer का उपयोग करना होगा।

फिर, छवि प्रारूप विनिर्देश ( http://en.wikipedia.org/wiki/JPEG या http://en.wikipedia.org/wiki/Portable_Network_Graphics ) के अनुसार सामग्री को पढ़ने के लिए एक DataView का उपयोग करें ।

छवि डेटा संपीड़न से निपटना कठिन होगा, लेकिन यह एक कोशिश से भी बदतर है। दूसरी ओर, आप अपनी छवि को छोटा बनाने के लिए PNG हेडर या JPEG एक्सिफ डेटा को हटाने का प्रयास कर सकते हैं, ऐसा करना आसान होना चाहिए।

आपको किसी अन्य बफ़र पर एक और DataWiew बनाना होगा और इसे फ़िल्टर्ड छवि सामग्री के साथ भरना होगा। उसके बाद, आपको बस विंडो में डेटा कंटेंट को एनकोड करना होगा।

मुझे बताएं कि यदि आप कुछ इसी तरह लागू करते हैं, तो कोड के माध्यम से जाना दिलचस्प होगा।


शायद आपने इसे पोस्ट करने के बाद कुछ बदल दिया है, लेकिन उस कैनवास पर दूसरा तर्क ।toDataURL आपके द्वारा बताए गए फ़ंक्शन में उस संपीड़न की मात्रा है जिसे आप लागू करना चाहते हैं।
wp-overwatch.com

2

मुझे लगता है कि स्वीकृत उत्तर की तुलना में सरल समाधान है।

  • HTML5 FileReader API का उपयोग करके फ़ाइलों को पढ़ें .readAsArrayBuffer
  • फ़ाइल डेटा के साथ एक बूँद बनाएँ और इसके साथ यूआरएल प्राप्त करें window.URL.createObjectURL(blob)
  • नया इमेज एलिमेंट बनाएं और सेट करें यह src फाइल ब्लॉब यूआरएल के लिए है
  • छवि को कैनवास पर भेजें। कैनवास का आकार वांछित आउटपुट आकार पर सेट है
  • स्केल्ड-डाउन डेटा को कैनवास से वापस प्राप्त करें (अपना स्वयं का आउटपुट स्वरूप और गुणवत्ता सेट करें)canvas.toDataURL("image/jpeg",0.7)
  • नए छिपे हुए इनपुट को मूल रूप में संलग्न करें और डेटारी छवियों को मूल रूप से सामान्य पाठ के रूप में स्थानांतरित करें
  • बैकएंड पर, डेटारी पढ़ें, बेस 64 से डीकोड करें, और इसे सहेजें

आपके प्रश्न के अनुसार:

क्या अपलोड करने से पहले एक छवि (अधिकतर jpeg, png और gif) को सीधे ब्राउज़र-साइड पर संपीड़ित करने का एक तरीका है

मेरा समाधान:

  1. फ़ाइल के साथ सीधे एक बूँद बनाएँ URL.createObjectURL(inputFileElement.files[0])

  2. स्वीकृत उत्तर के रूप में भी।

  3. स्वीकृत उत्तर के समान। इस बात का उल्लेख करते हुए कि, कैनवस का आकार आवश्यक है और उपयोग img.widthऔर img.heightसेट canvas.widthऔर canvas.height। नहीं है img.clientWidth

  4. द्वारा स्केल-डाउन छवि प्राप्त करें canvas.toBlob(callbackfunction(blob){}, 'image/jpeg', 0.5)। सेटिंग 'image/jpg'का कोई प्रभाव नहीं है। image/pngभी समर्थित है। एक नया बनाने Fileके अंदर वस्तु callbackfunction शरीर के साथ let compressedImageBlob = new File([blob])

  5. नए छिपे इनपुट जोड़ें या जावास्क्रिप्ट के माध्यम से भेजें । सर्वर को कुछ भी डिकोड नहीं करना है।

चेक https://javascript.info/binary सभी जानकारी के लिए। मैंने इस अध्याय को पढ़ने के बाद समाधान निकाला।


कोड:

    <!DOCTYPE html>
    <html>
    <body>
    <form action="upload.php" method="post" enctype="multipart/form-data">
      Select image to upload:
      <input type="file" name="fileToUpload" id="fileToUpload" multiple>
      <input type="submit" value="Upload Image" name="submit">
    </form>
    </body>
    </html>

यह कोड अन्य उत्तरों की तुलना में कम डरावना है।

अपडेट करें:

एक को सब कुछ अंदर रखना है img.onload। अन्यथा canvasसमय canvasनियत होने पर छवि की चौड़ाई और ऊँचाई को सही ढंग से प्राप्त नहीं कर पाएंगे ।

    function upload(){
        var f = fileToUpload.files[0];
        var fileName = f.name.split('.')[0];
        var img = new Image();
        img.src = URL.createObjectURL(f);
        img.onload = function(){
            var canvas = document.createElement('canvas');
            canvas.width = img.width;
            canvas.height = img.height;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0);
            canvas.toBlob(function(blob){
                    console.info(blob.size);
                    var f2 = new File([blob], fileName + ".jpeg");
                    var xhr = new XMLHttpRequest();
                    var form = new FormData();
                    form.append("fileToUpload", f2);
                    xhr.open("POST", "upload.php");
                    xhr.send(form);
            }, 'image/jpeg', 0.5);
        }
    }

3.4MB .pngimage/jpegतर्क सेट के साथ फ़ाइल संपीड़न परीक्षण ।

    |0.9| 777KB |
    |0.8| 383KB |
    |0.7| 301KB |
    |0.6| 251KB |
    |0.5| 219kB |

0

JPG छवि संपीड़न के लिए आप JIC (जावास्क्रिप्ट छवि संपीड़न) नामक सर्वोत्तम संपीड़न तकनीक का उपयोग कर सकते हैं, यह निश्चित रूप से आपकी मदद करेगा -> https://github.com/brunobar79/JIC


1
गुणवत्ता को कम किए बिना
Lifeisbeautiful

0

मैंने इस कार्य को बेहतर बनाया है:

var minifyImg = function(dataUrl,newWidth,imageType="image/jpeg",resolve,imageArguments=0.7){
    var image, oldWidth, oldHeight, newHeight, canvas, ctx, newDataUrl;
    (new Promise(function(resolve){
      image = new Image(); image.src = dataUrl;
      log(image);
      resolve('Done : ');
    })).then((d)=>{
      oldWidth = image.width; oldHeight = image.height;
      log([oldWidth,oldHeight]);
      newHeight = Math.floor(oldHeight / oldWidth * newWidth);
      log(d+' '+newHeight);

      canvas = document.createElement("canvas");
      canvas.width = newWidth; canvas.height = newHeight;
      log(canvas);
      ctx = canvas.getContext("2d");
      ctx.drawImage(image, 0, 0, newWidth, newHeight);
      //log(ctx);
      newDataUrl = canvas.toDataURL(imageType, imageArguments);
      resolve(newDataUrl);
    });
  };

इसका उपयोग:

minifyImg(<--DATAURL_HERE-->,<--new width-->,<--type like image/jpeg-->,(data)=>{
   console.log(data); // the new DATAURL
});

का आनंद लें ;)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.