सर्वर पर अपलोड करने से पहले जावास्क्रिप्ट के साथ क्लाइंट-आकार का चित्र


147

मैं जावास्क्रिप्ट के साथ एक छवि क्लाइंट-साइड का आकार बदलने का एक तरीका ढूंढ रहा हूं (वास्तव में आकार बदलें, न कि केवल चौड़ाई और ऊंचाई बदलें)।
मुझे पता है कि फ्लैश में ऐसा करना संभव है लेकिन अगर संभव हो तो मैं इससे बचना चाहूंगा।

क्या वेब पर कहीं कोई खुला स्रोत एल्गोरिदम है?


आपमें से जो अभी भी इसका उत्तर जानना चाहते हैं, आप यह कर सकते हैं, लेकिन आपको इमेज प्रोसेसिंग के लिए कुछ अजाक्स कॉल करने की आवश्यकता होगी।
पॉलीहेड्रॉन

1
'बनाने की ज़रुरत है'? वैसे आप इसे सर्वर पर हल कर सकते हैं और AJAX कॉल के माध्यम से पारदर्शी डेटा प्राप्त कर सकते हैं। लेकिन पूरी कोशिश इसे क्लाइंट साइड में करने की है, और जेरेमी बताते हैं कि ऐसा किया जा सकता है। मुझे लगता है कि यह एक महान उदाहरण है: github.com/rossturner/HTML5-ImageUploader
बार्ट

2
अपने नवीनतम संस्करण के साथ, Dropzone.js अपलोड करने से पहले ग्राहक पक्ष की छवि का समर्थन करता है।
user1666456

जवाबों:


111

यहाँ एक जिस्ट है जो यह करता है: https://gist.github.com/dcollien/312bce1270a5f511bf4a

(एक es6 संस्करण, और एक .js संस्करण जो एक स्क्रिप्ट टैग में शामिल किया जा सकता है)

आप इसका उपयोग इस प्रकार कर सकते हैं:

<input type="file" id="select">
<img id="preview">
<script>
document.getElementById('select').onchange = function(evt) {
    ImageTools.resize(this.files[0], {
        width: 320, // maximum width
        height: 240 // maximum height
    }, function(blob, didItResize) {
        // didItResize will be true if it managed to resize it, otherwise false (and will return the original file as 'blob')
        document.getElementById('preview').src = window.URL.createObjectURL(blob);
        // you can also now upload this blob using an XHR.
    });
};
</script>

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

(यह भी gif छवियों की अनदेखी करता है - यदि वे एनिमेटेड हैं)


2
मुझे लगता है कि आपको इसके लिए लगभग पर्याप्त प्रशंसा नहीं मिली है - मुझे लगता है कि यह बहुत अच्छा काम करता है और सुपर आसान है। साझा करने के लिए धन्यवाद!
मैट

4
हम्म..मैं को इसके साथ अच्छी सफलता मिली, लेकिन मैंने पाया कि मेरी छवियों (आकार के अलावा) में भी गुणवत्ता का भारी नुकसान हुआ (गंभीर पिक्सेलन के रूप में), हालांकि इसे सही रिज़ॉल्यूशन पर आउटपुट किया गया था।
रुबिन मार्टिनेज जूनियर।

1
नमस्ते, मुझे इस तरह का उपयोग करने के लिए एक स्निपेट की आवश्यकता है, और मुझे लगता है कि यह बहुत अच्छा है लेकिन .. फ़ंक्शन (बूँद, didItResize) {// didItResize यह सही होगा अगर इसे आकार देने में कामयाब रहे, अन्यथा झूठे (और मूल वापस आ जाएंगे) फ़ाइल को 'ब्लॉब' के रूप में दर्ज करें। डॉक्यूमेंट.गेटईमेंटबाइ ('पूर्वावलोकन')। src = window.URL.createObjectURL (बूँद); // आप अब एक XHR का उपयोग करके भी इस blob को अपलोड कर सकते हैं। यहाँ मुझे एक समस्या है .. मैं इस छवि को केवल फ़ॉर्म सबमिट करने के साथ कैसे भेज सकता हूँ। मेरा मतलब है, सबमिट बटन द्वारा ट्रिगर किए गए पोस्ट अनुरोध की तरह। तुम्हें पता है, हमेशा की तरह। धन्यवाद के लिए धन्यवाद!
iedmrc

3
गुणवत्ता (resampling) का नुकसान होने किसी के लिए, सेट करने के लिए कैनवास संदर्भ अद्यतन imageSmoothingEnabledTRUE` के रूप में और imageSmoothingQualityके लिए high। टाइपस्क्रिप्ट में जो ब्लॉक दिखता है: const ctx = canvas.getContext('2d'); ctx.imageSmoothingEnabled = true; (ctx as any).imageSmoothingQuality = 'high'; ctx.drawImage(image, 0, 0, width, height);
सीन पर्किन्स

1
क्या यह एक npm पैकेज बनाने का मौका है? सुपर शानदार होगा!
erksch

62

इसका उत्तर हां में है - एचटीएमएल 5 में आप कैनवास तत्व का उपयोग करके चित्र क्लाइंट-साइड का आकार बदल सकते हैं। आप नया डेटा भी ले सकते हैं और सर्वर पर भेज सकते हैं। इस ट्यूटोरियल देखें:

http://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/


28
यह एक लिंक-केवल उत्तर है और इस तरह की टिप्पणी होनी चाहिए।
Jimbo

2
canvas.mozGetAsFile ( "foo.png"); एक पदावनत समारोह है
मिली

12

अगर आप अपलोड करने से पहले रिसाइज कर रहे थे तो मुझे पता चला कि यह http://www.plupload.com/

यह किसी भी कल्पनीय विधि में आपके लिए सभी जादू करता है।

दुर्भाग्य से HTML5 आकार केवल मोज़िला ब्राउज़र के साथ समर्थित है, लेकिन आप अन्य ब्राउज़र को फ्लैश और सिल्वरलाइट पर पुनर्निर्देशित कर सकते हैं।

मैंने अभी इसकी कोशिश की और इसने मेरे एंड्रॉइड के साथ काम किया!

मैं http://swfupload.org/ का उपयोग कर रहा था , यह बहुत अच्छी तरह से काम करता है, लेकिन आकार आकार बहुत छोटा है। (सीमा याद नहीं कर सकते) और html 4 पर वापस नहीं जाता है जब फ्लैश उपलब्ध नहीं है।


44
ग्राहक-पक्ष का आकार बदलना तब अच्छा लगता है जब कोई उपयोगकर्ता 10mb फ़ोटो अपलोड करने का प्रयास करता है, जो केवल बहुत छोटी फ़ोटो के रूप में संग्रहीत होने वाली होती है। यह इस तरह से बहुत जल्दी अपलोड करेगा।
काइल

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

1
सावधान रहें क्योंकि plupload AGPL है।
एलेक्स

11

http://nodeca.github.io/pica/demo/

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

  1. आपके पास प्रति चैनल केवल 8 बिट्स होंगे (जेपीईजी में बेहतर गतिशील रेंज, लगभग 12 बिट्स हो सकती हैं)। यदि आप पेशेवर फ़ोटो अपलोड नहीं करते हैं, तो यह समस्या नहीं होनी चाहिए।
  2. एल्गोरिदम का आकार बदलने के बारे में सावधान रहें। ग्राहक पक्ष के अधिकांश पुनर्विक्रेता तुच्छ गणित का उपयोग करते हैं, और परिणाम इससे भी बदतर हो सकता है।
  3. आपको नीचे की छवि को तेज करने की आवश्यकता हो सकती है।
  4. यदि आप मूल से मेटाडेटा (एक्जिफ़ और अन्य) का पुन: उपयोग करना चाहते हैं - रंग प्रोफ़ाइल जानकारी को पट्टी करना न भूलें। क्योंकि यह तब लागू होता है जब आप छवि को कैनवास पर लोड करते हैं।

6

शायद कैनवास टैग के साथ (हालांकि यह पोर्टेबल नहीं है)। यहाँ कैनवास के साथ एक छवि को घुमाने के तरीके के बारे में एक ब्लॉग है , मुझे लगता है कि अगर आप इसे घुमा सकते हैं, तो आप इसका आकार बदल सकते हैं। शायद यह एक शुरुआती बिंदु हो सकता है।

इस पुस्तकालय को भी देखें ।


2
बहुत उपयोगी उदाहरण हैं। यदि आप कभी भी ये लिंक तोड़ते हैं, तो आप अपने उत्तर में एक स्निपेट या दो जोड़ना चाह सकते हैं।
ट्रेवर

4

आप सर्वर पर छवि अपलोड करने से पहले क्लाइंट-साइड इमेज प्रोसेसिंग के लिए एक जावास्क्रिप्ट इमेज प्रोसेसिंग फ्रेमवर्क का उपयोग कर सकते हैं।

नीचे मैंने निम्नलिखित पेज में उदाहरण के आधार पर एक रनवेबल कोड बनाने के लिए मार्विनज का उपयोग किया : "सर्वर पर अपलोड करने से पहले क्लाइंट-साइड में इमेज प्रोसेसिंग करना"

मूल रूप से मैं छवि को आकार देने के लिए मैरविन.काले (...) पद्धति का उपयोग करता हूं । फिर, मैं छवि को एक बूँद के रूप में अपलोड करता हूँ (विधि का उपयोग करके image.toBlob () )। सर्वर प्राप्त छवि का URL प्रदान करते हुए वापस उत्तर देता है।

/***********************************************
 * GLOBAL VARS
 **********************************************/
var image = new MarvinImage();

/***********************************************
 * FILE CHOOSER AND UPLOAD
 **********************************************/
 $('#fileUpload').change(function (event) {
	form = new FormData();
	form.append('name', event.target.files[0].name);
	
	reader = new FileReader();
	reader.readAsDataURL(event.target.files[0]);
	
	reader.onload = function(){
		image.load(reader.result, imageLoaded);
	};
	
});

function resizeAndSendToServer(){
  $("#divServerResponse").html("uploading...");
	$.ajax({
		method: 'POST',
		url: 'https://www.marvinj.org/backoffice/imageUpload.php',
		data: form,
		enctype: 'multipart/form-data',
		contentType: false,
		processData: false,
		
	   
		success: function (resp) {
       $("#divServerResponse").html("SERVER RESPONSE (NEW IMAGE):<br/><img src='"+resp+"' style='max-width:400px'></img>");
		},
		error: function (data) {
			console.log("error:"+error);
			console.log(data);
		},
		
	});
};

/***********************************************
 * IMAGE MANIPULATION
 **********************************************/
function imageLoaded(){
  Marvin.scale(image.clone(), image, 120);
  form.append("blob", image.toBlob());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<form id="form" action='/backoffice/imageUpload.php' style='margin:auto;' method='post' enctype='multipart/form-data'>
				<input type='file' id='fileUpload' class='upload' name='userfile'/>
</form><br/>
<button type="button" onclick="resizeAndSendToServer()">Resize and Send to Server</button><br/><br/>
<div id="divServerResponse">
</div>


यह भयानक लग रहा है!
पिम्बरवॉर्स

2

हां, आधुनिक ब्राउज़रों के साथ यह पूरी तरह से उल्लेखनीय है। यहां तक ​​कि विशेष रूप से किसी भी संख्या में कैनवास के परिवर्तनों को करने वाली एक बाइनरी फ़ाइल के रूप में फ़ाइल को अपलोड करने के बिंदु पर भी।

http://jsfiddle.net/bo40drmv/

(यह उत्तर यहाँ स्वीकृत उत्तर का सुधार है )

पीएचपी में परिणाम प्रस्तुत करने की प्रक्रिया को ध्यान में रखते हुए कुछ के साथ:

//File destination
$destination = "/folder/cropped_image.png";
//Get uploaded image file it's temporary name
$image_tmp_name = $_FILES["cropped_image"]["tmp_name"][0];
//Move temporary file to final destination
move_uploaded_file($image_tmp_name, $destination);

अगर कोई विटाली की बात को लेकर चिंतित है, तो आप काम करने वाले जैफल्ड पर कुछ क्रॉपिंग और आकार बदलने की कोशिश कर सकते हैं।


0

मेरे अनुभव में, यह उदाहरण एक संशोधित चित्र अपलोड करने के लिए सबसे अच्छा समाधान रहा है: https://zocada.com/compress-resize-images-javascript-browser/

इसमें एचटीएमएल 5 कैनवस फीचर का इस्तेमाल किया गया है।

कोड इस तरह 'सरल' है:

compress(e) {
    const fileName = e.target.files[0].name;
    const reader = new FileReader();
    reader.readAsDataURL(e.target.files[0]);
    reader.onload = event => {
        const img = new Image();
        img.src = event.target.result;
        img.onload = () => {
                const elem = document.createElement('canvas');
                const width = Math.min(800, img.width);
                const scaleFactor = width / img.width;
                elem.width = width;
                elem.height = img.height * scaleFactor;

                const ctx = elem.getContext('2d');
                // img.width and img.height will contain the original dimensions
                ctx.drawImage(img, 0, 0, width, img.height * scaleFactor);
                ctx.canvas.toBlob((blob) => {
                    const file = new File([blob], fileName, {
                        type: 'image/jpeg',
                        lastModified: Date.now()
                    });
                }, 'image/jpeg', 1);
            },
            reader.onerror = error => console.log(error);
    };
}

इस विकल्प के साथ केवल एक नकारात्मक पहलू है, और यह EXIF ​​डेटा की अनदेखी के कारण छवि रोटेशन से संबंधित है। जो मैं इस समय काम कर रहा हूं। मेरे द्वारा किए जाने के बाद अपडेट हो जाएगा।

एक और नकारात्मक पहलू, फाइट आईई / एज सपोर्ट की कमी है, जिस पर मैं काम कर रहा हूं। यद्यपि उपरोक्त लिंक में जानकारी है। दोनों मुद्दों के लिए।

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