ব্রাউজারে জাভাস্ক্রিপ্টের মাধ্যমে কোনও চিত্র সংকুচিত করবেন কীভাবে?


92

টিএল; ডিআর;

কোনও চিত্র আপলোড করার আগে সরাসরি ব্রাউজারের পাশে (বেশিরভাগ জেপিইগ, পিএনজি এবং জিআইএফ) সংকুচিত করার কোনও উপায় আছে? আমি নিশ্চিত যে জাভাস্ক্রিপ্ট এটি করতে পারে তবে আমি এটি অর্জনের কোনও উপায় খুঁজে পাচ্ছি না।


আমি বাস্তবায়ন করতে চাই পুরো দৃশ্যের এখানে:

  • ব্যবহারকারী আমার ওয়েবসাইটে যান, এবং একটি input type="file"উপাদান মাধ্যমে একটি চিত্র চয়ন করুন ,
  • এই চিত্রটি জাভাস্ক্রিপ্টের মাধ্যমে পুনরুদ্ধার করা হয়েছে, আমরা কিছু যাচাই করি যেমন সঠিক ফাইল ফর্ম্যাট, সর্বোচ্চ ফাইলের আকার ইত্যাদি,
  • যদি প্রতিটি জিনিস ঠিক থাকে, তবে চিত্রটির পূর্বরূপ পৃষ্ঠায় প্রদর্শিত হবে,
  • ব্যবহারকারী কিছু প্রাথমিক কাজ করতে পারে যেমন 90 ° / -90 by দ্বারা চিত্রটি ঘোরানো, প্রাক-সংজ্ঞায়িত অনুপাতের পরে এটি ক্রপ করুন বা ব্যবহারকারী অন্য চিত্র আপলোড করতে এবং পদক্ষেপ 1 এ ফিরে যেতে পারে,
  • যখন ব্যবহারকারী সন্তুষ্ট হন, সম্পাদিত চিত্রটি তখন সংকুচিত হয়ে স্থানীয়ভাবে "সংরক্ষণ করা হয়" (কোনও ফাইলে সংরক্ষণ করা যায় নি, তবে ব্রাউজারের মেমরি / পৃষ্ঠায়), -
  • নাম, বয়স ইত্যাদির মতো ডেটা সহ ব্যবহারকারী একটি ফর্ম পূরণ করুন
  • ব্যবহারকারী "সমাপ্তি" বোতামটিতে ক্লিক করেন, তারপরে ডেটা + সংক্ষেপিত চিত্রযুক্ত ফর্মটি সার্ভারে প্রেরণ করা হয় (এজেএক্স ছাড়াই),

শেষ ধাপ পর্যন্ত সম্পূর্ণ প্রক্রিয়াটি ক্লায়েন্টের পক্ষে করা উচিত এবং এটি সর্বশেষতম ক্রোম এবং ফায়ারফক্স, সাফারি 5+ এবং আই 8+ এর সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত । যদি সম্ভব হয় তবে কেবল জাভাস্ক্রিপ্ট ব্যবহার করা উচিত (তবে আমি নিশ্চিত যে এটি সম্ভব নয়)।

আমি এখনই কিছু কোড করি নি, তবে আমি ইতিমধ্যে এটি সম্পর্কে চিন্তা করেছি। ফাইল এপিআইয়ের মাধ্যমে স্থানীয়ভাবে ফাইল রিডিং সম্ভব , চিত্রের পূর্বরূপ এবং সম্পাদনা ক্যানভাস উপাদান ব্যবহার করে করা যেতে পারে তবে আমি চিত্রের সংকোচনের অংশটি করার কোনও উপায় খুঁজে পাচ্ছি না

এইচটিএমএল 5 প্লিজ ডটকম এবং ক্যানিউজ ডটকমের মতে , এই ব্রাউজারগুলিকে সমর্থন করা বেশ শক্ত (IE এর জন্য ধন্যবাদ) তবে এটি ফ্ল্যাশক্যানভাস এবং ফাইলরেডার হিসাবে পলিফিল ব্যবহার করে করা যেতে পারে ।

আসলে, লক্ষ্যটি ফাইলের আকার হ্রাস করা, তাই আমি সমাধান হিসাবে চিত্রের সংকোচনের বিষয়টি দেখি। তবে, আমি জানি যে আপলোড করা চিত্রগুলি আমার ওয়েবসাইটে প্রতিবার একই স্থানে প্রদর্শিত হতে চলেছে এবং আমি এই প্রদর্শন ক্ষেত্রটির মাত্রা জানি (যেমন 200x400)। সুতরাং, আমি এই মাত্রাগুলি ফিট করার জন্য চিত্রটির আকার পরিবর্তন করতে পারি, ফলে ফাইলের আকার হ্রাস করা যায়। এই কৌশলটির জন্য সংকোচনের অনুপাত কী হবে তা আমার কোনও ধারণা নেই।

আপনি কি মনে করেন ? আমাকে বলতে কোন পরামর্শ আছে? জাভাস্ক্রিপ্টে কোনও চিত্র ব্রাউজার-পাশ সংকুচিত করার কোনও উপায় কি আপনি জানেন? আপনার জবাবের জন্য ধন্যবাদ।

উত্তর:


165

সংক্ষেপে:

  • .ReadAsArrayBuffer সহ HTML5 ফাইলরেডার এপিআই ব্যবহার করে ফাইলগুলি পড়ুন
  • ফাইল ডেটা দিয়ে একটি ব্লব তৈরি করুন এবং উইন্ডো দিয়ে এর url পান URL
  • নতুন চিত্র উপাদান তৈরি করুন এবং এটি ব্লক ইউআরএল ফাইলের জন্য src সেট করুন
  • ছবিটি ক্যানভাসে প্রেরণ করুন। ক্যানভাস আকার পছন্দসই আউটপুট আকারে সেট করা আছে
  • ক্যানভাসের মাধ্যমে ক্যানভাস থেকে স্কেলড-ডাউন ডেটা ফিরে পান to
  • মূল ফর্মটিতে নতুন লুকানো ইনপুট সংযুক্ত করুন এবং ডেটাউরি চিত্রগুলি মূল পাঠ্য হিসাবে স্থানান্তর করুন
  • ব্যাকএন্ডে, ডেটা ইউআরআই পড়ুন, বেস 64 থেকে ডিকোড করুন এবং এটি সংরক্ষণ করুন

উত্স: কোড


4
অনেক ধন্যবাদ ! এই আমি খুঁজছিলাম ছিল। আপনি জানেন কী এই কৌশলটির সাথে সংকোচনের অনুপাতটি কতটা ভাল?
pomeh

4
@ নিকোলাস কাইরিয়াকাইডস আমি নিশ্চিত করতে পারি যে এটি canvas.toDataURL("image/jpeg",0.7)কার্যকরভাবে সংকুচিত করে, এটি 70 টি মানের (ডিফল্টের বিপরীতে, মানের 100) এর সাথে জেপিজি সংরক্ষণ করে।
ব্যবহারকারী 1111929

4
@ নিকোলাস কিরিয়াকাইডস, এটি তৈরি করা ভাল পার্থক্য নয়। বেশিরভাগ কোডেক লসহীন নয়, সুতরাং তারা আপনার "ডাউনস্কেলিং" সংজ্ঞা অনুসারে ফিট করবে (যেমন আপনি 100 এ ফিরে যেতে পারবেন না)।
বিলিবোবনেট

4
ডাউনস্কলিং উচ্চতা এবং প্রস্থের দিক থেকে একটি ছোট আকারের চিত্রগুলি তৈরি বোঝায়। এটি আসলে সংক্ষেপণ। এটি ক্ষতিকারক সংকোচনের তবে অবশ্যই সংকোচনের। এটি পিক্সেলগুলিকে ডাউনস্কলিং করছে না, এটি কিছু পিক্সেলকে একই রঙের দিকে ঠেলে দেয় যাতে সংক্ষেপণটি কম বিটগুলিতে সেই রঙগুলিকে আঘাত করতে পারে। জেপিইজি যাইহোক পিক্সেলগুলির জন্য সংকোচনে তৈরি করেছে, তবে ক্ষতিকারক মোডে এটি বলেছে যে কয়েকটি রঙের বন্ধকে একই রঙ বলা যেতে পারে। এটি এখনও সংকোচনের। গ্রাফিক্স সম্পর্কিত ডাউনসাইকেলিং সাধারণত প্রকৃত আকারের পরিবর্তনকে বোঝায়।
তাতারাইজ

4
আমি কেবল এটি বলতে চাই: URL.createObjectUrl()ফাইলটি কোনও ফোঁড়ায় রূপান্তর না করেই ফাইলটি সরাসরি যেতে পারে ; ফাইলটি একটি ব্লব হিসাবে গণনা করা হয়।
Hellol11

20

আমি অন্যান্য উত্তরগুলি থেকে দুটি জিনিস অনুপস্থিত দেখতে পাচ্ছি:

  • canvas.toBlob(যখন উপলভ্য থাকে) তত বেশি পারফরম্যান্ট হয় canvas.toDataURLএবং অ্যাসিঙ্কও হয়।
  • ফাইল -> চিত্র -> ক্যানভাস -> ফাইল রূপান্তর 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(...);
    });
};

টুব্লব আমার জন্য কৌতুকটি করেছিলেন, একটি ফাইল তৈরি করে এবং সার্ভারে $ _ ফাইলস অ্যারেটিতে পুনরুদ্ধার করে। ধন্যবাদ!
রিকার্ডো রুইজ রোমেরো

দুর্দান্ত লাগছে! তবে এটি কি সমস্ত ব্রাউজার, ওয়েব এবং মোবাইলে কাজ করবে? (আসুন
আইটি

14

@ সাইকোউডস এর উত্তর ভাল। আমি আমার নিজস্ব সমাধান দিতে চাই। এই জাভাস্ক্রিপ্ট ফাংশনটি একটি চিত্রের ডেটা ইউআরএল এবং একটি প্রস্থ নেয়, এটিকে নতুন প্রস্থে স্কেল করে এবং একটি নতুন ডেটা URL প্রদান করে returns

// 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 চান তা ব্যবহার করা যেতে পারে।


দয়া করে, আপনি আমাকে এই উদাহরণটি সম্পর্কে আরও বিস্তারিত জানাতে পারেন, কীভাবে ফাংশনটি কল করবেন এবং ফলাফল কীভাবে ফিরে এল?
ভিজুলো

এখানে একটি উদাহরণ রয়েছে: danielsadचर.info / Html / scaleimage.html এটি কীভাবে কাজ করে তা দেখতে পৃষ্ঠার উত্সটি পড়তে ভুলবেন না।
ভিভিয়ান নদী

4
web.archive.org/web/20171226190510/danielsadventure.info/Html/… অন্যান্য লোকেরা যারা লিঙ্কের প্রস্তাবটি পড়তে চান @ ড্যানিয়েল অ্যালেনল্যাংডন
সেড্রিক আর্নল্ড

শীর্ষস্থান হিসাবে, কখনও কখনও চিত্র.উইউথ / উচ্চতা 0 ফিরে আসবে কারণ এটি লোড হয়নি। আপনার এটিকে একটি অ্যাসিঙ্ক ফাংশনে রূপান্তর করতে হবে এবং ইমেজ.অনলোড শুনতে হবে সঠিক চিত্র এবং উচ্চতা সহ সঠিক চিত্র পেতে।
ম্যাট পোপ

9

আপনি চিত্র-রূপান্তরটি একবার দেখে নিতে পারেন , এটি এখানে চেষ্টা করুন -> ডেমো পৃষ্ঠা

এখানে চিত্র বর্ণনা লিখুন


4
সংযুক্ত সংস্থান সম্পর্কে কিছু তথ্য যুক্ত করুন
সানসোলো

এই উত্তরটি নিখুঁত!
djcaesar9114

ডেমো পৃষ্ঠার লিঙ্কটি নষ্ট হয়ে গেছে। : আপনি এখানে পরীক্ষা করতে পারেন demo.wangyulue.com/image-conversion
gabrielstuff

4

আমি এতে একটি সমস্যা ছিল downscaleImage()ফাংশন @ ড্যানিয়েল-অ্যালেন-ল্যাংডন উপরে পোস্ট যে 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

সম্পাদনা: মিস্টার মিঃ এই উত্তরের মন্তব্য অনুসারে, দেখে মনে হচ্ছে যে সংক্ষেপণ এখন জেপিজি / ওয়েবপি ফর্ম্যাটগুলির জন্য উপলব্ধ ( https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL দেখুন ) ।

আমি যতদূর জানি, আপনি ক্যানভাস ব্যবহার করে চিত্রগুলি সঙ্কুচিত করতে পারবেন না, পরিবর্তে, আপনি এটির আকার পরিবর্তন করতে পারেন। ক্যানভাস.টোডাটাআরএল ইউআরএল ব্যবহার করা আপনাকে সংকোচনের অনুপাত বেছে নিতে দেয় না। আপনি ক্যানিমেজটি একবারে দেখতে পারেন যা আপনি যা চান ঠিক তেমন করে: https://github.com/nfroidure/CanImage/blob/master/chrome/canimage/content/canimage.js

প্রকৃতপক্ষে, চিত্রটির আকার হ্রাস করতে প্রায়শই এটির আকার পরিবর্তন করার পক্ষে যথেষ্ট তবে আপনি যদি আরও এগিয়ে যেতে চান তবে আপনাকে চিত্রের ডেটা সম্বলিত একটি বাফার পেতে নতুন প্রবর্তিত পদ্ধতি ফাইলটি ব্যবহার করতে হবে readআডআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআআসসসাইনস প্রকৃতপক্ষে চিত্রটির আকার হ্রাস করার জন্য এটি কেবলমাত্র আকার পরিবর্তন করতে যথেষ্ট তবে আপনি আরও নতুন পদ্ধতিতে ব্যবহার করতে হবে।

তারপরে, চিত্র ফর্ম্যাট স্পেসিফিকেশন ( http://en.wikedia.org/wiki/JPEG বা http://en.wikedia.org/wiki/Portable_Network_Graphics ) অনুযায়ী এর সামগ্রীটি পড়তে কেবল একটি ডেটাভিউ ব্যবহার করুন ।

চিত্রের ডেটা সংকোচনের সাথে মোকাবিলা করা শক্ত হবে, তবে এটি আরও খারাপ চেষ্টা। অন্যদিকে, আপনি নিজের চিত্র আরও ছোট করতে পিএনজি শিরোনাম বা জেপিজি এক্সিফ ডেটা মুছতে চেষ্টা করতে পারেন, এটি করা আরও সহজ হওয়া উচিত।

আপনাকে অন্য একটি বাফারে অন্য ডেটাভিউ তৈরি করতে হবে এবং ফিল্টারকৃত চিত্রের সামগ্রী দিয়ে এটি পূরণ করতে হবে। তারপরে, আপনাকে উইন্ডো.বিটোয়া ব্যবহার করে আপনার চিত্রের সামগ্রীটি ডেটাউরিআইতে এনকোড করতে হবে।

আপনি যদি অনুরূপ কিছু বাস্তবায়ন করেন তবে আমাকে জানান, কোডটি দিয়ে যাওয়া আকর্ষণীয় হবে।


আপনি পোস্ট করার পরে সম্ভবত কিছু পরিবর্তন হয়েছে তবে আপনি যে ক্যানভাস.টোডাটাআরএল ফাংশনের উল্লেখ করেছেন তার দ্বিতীয় যুক্তি হ'ল আপনি প্রয়োগ করতে চান এমন সংকোচনের পরিমাণ।
wp-overwatch.com

2

আমি দেখতে পেয়েছি যে গৃহীত উত্তরের তুলনায় আরও সহজ সমাধান রয়েছে।

  • এইচটিএমএল 5 ফাইলরেডার এপিআই ব্যবহার করে ফাইলগুলি পড়ুন .readAsArrayBuffer
  • ফাইল ডেটা দিয়ে একটি ব্লব তৈরি করুন এবং এর ইউআরএল পাবেন window.URL.createObjectURL(blob)
  • নতুন চিত্র উপাদান তৈরি করুন এবং এটি ব্লক ইউআরএল ফাইলের জন্য src সেট করুন
  • ছবিটি ক্যানভাসে প্রেরণ করুন। ক্যানভাস আকার পছন্দসই আউটপুট আকারে সেট করা আছে
  • ক্যানভাস থেকে ছোটো-ডাউন ডেটা ফেরত পাওয়ার মাধ্যমে canvas.toDataURL("image/jpeg",0.7)(আপনার নিজের আউটপুট ফরম্যাট এবং মান সেট)
  • মূল ফর্মটিতে নতুন লুকানো ইনপুট সংযুক্ত করুন এবং ডেটাউরি চিত্রগুলি মূল পাঠ্য হিসাবে স্থানান্তর করুন
  • ব্যাকএন্ডে, ডেটা ইউআরআই পড়ুন, বেস 64 থেকে ডিকোড করুন এবং এটি সংরক্ষণ করুন

আপনার প্রশ্ন অনুসারে:

কোনও চিত্র আপলোড করার আগে সরাসরি ব্রাউজারের পাশে (বেশিরভাগ জেপিইগ, পিএনজি এবং জিআইএফ) সংকুচিত করার কোনও উপায় আছে কি?

আমার সমাধান:

  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

জেপিজি চিত্রের সংক্ষেপণের জন্য আপনি জেআইসি (জাভাস্ক্রিপ্ট চিত্র সংক্ষেপণ) নামক সেরা সংকোচন কৌশলটি ব্যবহার করতে পারেন এটি অবশ্যই আপনাকে সহায়তা করবে -> https://github.com/brunobar79/JIC


4
মানের হ্রাস ছাড়া
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
});

উপভোগ করুন;)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.