জেএস ক্লায়েন্ট-সাইড এক্সিফ ওরিয়েন্টেশন: ঘোরান এবং মিরর জেপিইজি চিত্রগুলি


154

ডিজিটাল ক্যামেরার ফটোগুলি প্রায়শই একটি এক্সিএফ "ওরিয়েন্টেশন" ট্যাগ সহ জেপিগ হিসাবে সংরক্ষণ করা হয়। সঠিকভাবে প্রদর্শন করার জন্য, কোন ওরিয়েন্টেশনটি সেট করা আছে তার উপর নির্ভর করে চিত্রগুলি ঘোরানো / মিরর করা দরকার, তবে ব্রাউজারগুলি চিত্রটি রেন্ডারিংয়ে এই তথ্য উপেক্ষা করে। এমনকি বড় বাণিজ্যিক ওয়েব অ্যাপ্লিকেশনগুলিতে, এক্সআইএফ ওরিয়েন্টেশনের জন্য সমর্থন স্পটটি 1 হতে পারে । একই উত্সটি কোনও জেপিগের কাছে থাকতে পারে এমন 8 টি ভিন্ন ধরণের একটি সুন্দর সংক্ষিপ্তসার সরবরাহ করে :

এক্সআইএফ ওরিয়েন্টেশনগুলির সংক্ষিপ্তসার

নমুনা চিত্র 4 এ পাওয়া যায় ।

প্রশ্নটি কীভাবে ক্লায়েন্টের পাশে চিত্রটি ঘোরানো / মিরর করা যায় যাতে এটি সঠিকভাবে প্রদর্শিত হয় এবং প্রয়োজনে আরও প্রক্রিয়া করা যায়?

ওরিয়েন্টেশন অ্যাট্রিবিউট 2 সহ EXIF ​​ডেটা পার্স করার জন্য এখানে জেএস লাইব্রেরি রয়েছে । ফ্লিকার বড় চিত্রগুলি বিশ্লেষণ করার সময় সম্ভাব্য পারফরম্যান্স সমস্যার কথা বলেছিল এবং ওয়েবকার্স 3 ব্যবহারের প্রয়োজন ।

কনসোল সরঞ্জামগুলি চিত্রগুলি 5 টি পুনরায় সঠিকভাবে পরিচালনা করতে পারে । সমস্যা সমাধানের জন্য একটি পিএইচপি স্ক্রিপ্ট 6 এ উপলব্ধ

উত্তর:


145

গিথুব প্রকল্প জাভাস্ক্রিপ্ট-লোড-চিত্রটি এক্সিএফ ওরিয়েন্টেশন সমস্যাটির সম্পূর্ণ সমাধান সরবরাহ করে, সমস্ত 8 টি এক্সেস্ট ওরিয়েন্টেশনের জন্য চিত্রগুলি সঠিকভাবে ঘোরানো / মিরর করে। জাভাস্ক্রিপ্ট এক্সিফ অরিয়েন্টেশন এর অনলাইন ডেমো দেখুন

চিত্রটি একটি HTML5 ক্যানভাসে আঁকা onto এর সঠিক রেন্ডারিংটি ক্যানভাস অপারেশনের মাধ্যমে জেএস / লোড-ইমেজ-ওরিয়েন্টেশন.জেজে প্রয়োগ করা হয়েছে ।

আশা করি এটি অন্য কারও কিছু সময় সাশ্রয় করেছে এবং অনুসন্ধানের ইঞ্জিনগুলি এই মুক্ত উত্স রত্ন সম্পর্কে শেখায় :)


1
আমি এই লাইব্রেরিটি ব্যবহার করছি তবে সম্প্রতি এটি আইওএস 8.3-এ ভেঙে গেছে যেখানে এটি আমার সবচেয়ে বেশি কাজ করার প্রয়োজন :(
গর্ডন সান

2
এটি কীভাবে সহায়ক তা দেখার জন্য আমি সত্যিই সংগ্রাম করছি। আমি এটি শিখতে চেষ্টা করে এদিক সেদিক খেলছি যাতে আমি হয় একটি পৃষ্ঠা বিশ্লেষণ করতে পারি এবং চিত্রগুলি যখন ঘোরানো দরকার হয় তখন ঘুরিয়ে দিতে পারি, বা প্রকৃতপক্ষে এটি আপলোড করার আগে অরিয়েন্টেশন এবং রোটেশন ফাইলটি (কোনওভাবে) সনাক্ত করতে পারি। ডেমো না। এটি কেবল একটি ফাইল ইনপুট থেকে একটি ফাইল নেয় এবং এটি সঠিক উপায়ে প্রদর্শন করে, আসল বিশ্বে এটি কখন কার্যকর? আমি যখন আমার পৃষ্ঠাটি বিশ্লেষণ করি এবং লোড ইমেজ লাইব্রেরিতে চিত্রের ট্যাগগুলি থেকে URL গুলি ফিড করি তখন কোনও এক্সিফ ডেটা থাকে না তাই এটি করতে পারে না। আপলোডের জন্য এটি একটি ক্যানভাস অবজেক্ট ফেরত দেয় তাই আমি এটি সার্ভারে বা অন্য কিছুতে প্রেরণ করতে পারি না।
ইগনোসর

3
@ আইগনোসর: আপনি সার্ভারের সাথে বেস 64 এনকোডড ডেটা প্রেরণ canvas.toDataURL()এবং ডিকোড এবং এটি সার্ভারের পাশে সংরক্ষণ করতে পারেন।
br4nnigan

1
লোড-চিত্র প্রকল্পটি ব্যবহার করার পরিবর্তে, আপনি নিজের বেক করার জন্য এর কয়েকটি কোড-বেস ব্যবহার করতে পারেন - কেবল github.com / ব্লুয়িম্প / জাভা স্ক্রিপ্ট- লোড- চিত্র / ব্লব / মাস্টার / জেএস / … দেখুন…
অ্যান্ডি লরেঞ্জ

1
এই লাইব্রেরিটি নিয়মিত <img>ট্যাগের মতো প্রতিক্রিয়া সৃষ্টি করে এমন ক্যানভাস তৈরি করার কোনও উপায় আছে কি ?
এরিক বার্কুন-ড্রেভনিগ

103

মেডারের প্রসঙ্গে রূপান্তরটি পুরোপুরি কার্যকর হয়। যদি আপনাকে অরিয়েন্টেশনটি নিষ্কাশনের প্রয়োজন হয় কেবলমাত্র এই ফাংশনটি ব্যবহার করুন - আপনার কোনও এক্সআইএফ-পড়ার ল্যাব দরকার নেই। নীচে বেস 64 ইমেজে ওরিয়েন্টেশন পুনরায় সেট করার জন্য একটি ফাংশন রয়েছে। এখানে এটির জন্য একটি বেহালতাওরিয়েন্টেশন এক্সট্রাকশন ডেমো সহ আমি একটি ফিডলও প্রস্তুত করেছি ।

function resetOrientation(srcBase64, srcOrientation, callback) {
  var img = new Image();    

  img.onload = function() {
    var width = img.width,
        height = img.height,
        canvas = document.createElement('canvas'),
        ctx = canvas.getContext("2d");

    // set proper canvas dimensions before transform & export
    if (4 < srcOrientation && srcOrientation < 9) {
      canvas.width = height;
      canvas.height = width;
    } else {
      canvas.width = width;
      canvas.height = height;
    }

    // transform context before drawing image
    switch (srcOrientation) {
      case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
      case 3: ctx.transform(-1, 0, 0, -1, width, height); break;
      case 4: ctx.transform(1, 0, 0, -1, 0, height); break;
      case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
      case 6: ctx.transform(0, 1, -1, 0, height, 0); break;
      case 7: ctx.transform(0, -1, -1, 0, height, width); break;
      case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
      default: break;
    }

    // draw image
    ctx.drawImage(img, 0, 0);

    // export base64
    callback(canvas.toDataURL());
  };

  img.src = srcBase64;
};

7
ওরিয়েন্টেশনের ক্ষেত্রে ডিফল্ট কেসের switchপ্রয়োজন হয় না, যেহেতু সেই রূপান্তরটি কিছুই করে না। এছাড়াও, srcOrientation > 4 && srcOrientation < 9পরিবর্তে ব্যবহার করার কথা বিবেচনা করুন [5,6,7,8].indexOf(srcOrientation) > -1, কারণ এটি দ্রুত এবং কম সংস্থান নিবিড় (উভয় র‌্যাম এবং সিপিইউ)। সেখানে অ্যারে রাখার দরকার নেই। প্রচুর চিত্রের ব্যাচ করার সময় এটি গুরুত্বপূর্ণ, যেখানে প্রতিটি বিট গণনা করা হয়। অন্যথায়, বেশ ভাল উত্তর। সম্মত!
রায়ান ক্যাসাস

4
@ রায়ানকাসাস indexOfআপনার প্রস্তাবের সাথে তুলনা করে কতটা ভারী হতে পারে তা আমি জানতাম না । আমি 10 এম পুনরাবৃত্তি সহ একটি সাধারণ লুপ চালিয়েছিলাম এবং এটি 1400% দ্রুত ছিল। চমৎকার: ডি ধন্যবাদ একটি গুচ্ছ!
ওয়ান্ডারবার্ট

1
আমি এই উত্তরটি অ্যান্ড্রয়েড ওয়েবভিউতে ব্যবহার করেছি এবং এটি প্রমাণিত হয়েছে যে কয়েকটি অ্যান্ড্রয়েড ডিভাইস রয়েছে যা ওয়েবভিউয়ের মধ্যে ওয়েবজিএল সমর্থন করে না (দেখুন bugs.chromium.org/p/chromium/issues/detail?id=555116 ) চিত্রের আকারের উপর নির্ভর করে এই জাতীয় ডিভাইসগুলিতে রোটেশনটি খুব দীর্ঘ সময় নিতে পারে।
ndreisg

1
রেফারেন্স সহ যখন ব্যবহার করা হয় তখন getOrientationআমি কৌতূহল করি যে এটি পারফরম্যান্সের ক্ষেত্রে কার্যকর কিনা whether getOrientationকল করে fileReader.readAsArrayBuffer, এবং তারপরে আমরা কল URL.createObjectURLকরে ফলাফলটি পাস করি resetOrientation, যা এই URL টি চিত্র হিসাবে লোড করে। এর অর্থ কি এই চিত্র ফাইলটি "লোড" হয়ে যাবে / একবার ব্রাউজার দ্বারা নয় একবার পড়বে, না আমি ভুল বুঝব?
অলিভার জোসেফ অ্যাশ

1
এছাড়াও, যেখানে ব্রাউজারগুলি ইতিমধ্যে সম্মান জানানো হবে সেগুলি সম্পর্কে কী করবেন? আমি বিশ্বাস করি এটি আইওএস সাফারি এবং ব্রাউজারগুলিতে সিএসএস image-orientation: from-imageব্যবহার করার সময় সমর্থন করে ।
অলিভার জোসেফ অ্যাশ

40

যদি

width = img.width;
height = img.height;
var ctx = canvas.getContext('2d');

তারপরে আপনি চিত্রটি ওরিয়েন্টেশন 1-এ পরিণত করতে এই রূপান্তরগুলি ব্যবহার করতে পারেন

ওরিয়েন্টেশন থেকে:

  1. ctx.transform(1, 0, 0, 1, 0, 0);
  2. ctx.transform(-1, 0, 0, 1, width, 0);
  3. ctx.transform(-1, 0, 0, -1, width, height);
  4. ctx.transform(1, 0, 0, -1, 0, height);
  5. ctx.transform(0, 1, 1, 0, 0, 0);
  6. ctx.transform(0, 1, -1, 0, height, 0);
  7. ctx.transform(0, -1, -1, 0, height, width);
  8. ctx.transform(0, -1, 1, 0, 0, width);

সিটিএক্স এ ছবি আঁকার আগে


58
এখানে কি ঘটছে?
মুহাম্মদ উমার

1
এটির সাথে আপনাকে কেবল ওরিয়েন্টেশনটি জানতে হবে (উদাহরণস্বরূপ EXIF ​​এর মাধ্যমে) এবং তারপরে প্রয়োজন অনুসারে ঘোরানো হবে। আমি যা খুঁজছি তার অর্ধেক।
ব্রেন্ডেন

2
এই রূপান্তরগুলি আমার পক্ষে কার্যকর হয়নি - পরিবর্তে আমি github.com/blueimp/JavaScript-Load-Image/blob/master/js/… এ লোড-চিত্র প্রকল্পের কোডটি ব্যবহার করেছি যা আমি বিশ্বাস করি তা প্রমাণিত কোডটি প্রমাণিত করার জন্য যা ক্যানভাস প্রসঙ্গে প্লাস প্রস্থ / উচ্চতার অদলবদল, ট্রান্সলেট, ঘোরানো উভয়ই ব্যবহার করে। রূপান্তরকরণ ইত্যাদির অন্যান্য প্রচেষ্টা নিয়ে বহু ঘন্টা পরীক্ষার পরে আমাকে 100% ফলাফল দিয়েছিলেন
অ্যান্ডি লরেঞ্জ

1
আপনি যখন চিত্রটি সিটিএক্স এ আঁকেন তখন কেন এটি গুরুত্বপূর্ণ? আপনি কোনও ছবি আঁকার পরে ক্যানভাসটি ঘোরতে পারবেন না?
AlxVallejo

অরিয়েন্টেশন 8 এর জন্য আবর্তন আমার পক্ষে এইভাবে কাজ করে: ctx.transfor (0, -1, 1, 0, 0, উচ্চতা);
জর্জিও বারচিয়েসি

24

ঠিক আছে @ ব্যবহারকারী 3096626 উত্তর ছাড়াও আমি মনে করি যদি কেউ কোড উদাহরণ সরবরাহ করে তবে এটি আরও বেশি সহায়ক হবে, নিম্নলিখিত উদাহরণটি আপনাকে url (দূরবর্তী চিত্র) থেকে আসে কীভাবে চিত্রের ওরিয়েন্টেশনটি ঠিক করতে হবে তা দেখায়:


সমাধান 1: জাভাস্ক্রিপ্ট ব্যবহার করে (প্রস্তাবিত)

  1. কারণ লোড ইমেজ লাইব্রেরি URL চিত্রগুলি শুধুমাত্র (ফাইল / ফোঁটা) থেকে Exif ট্যাগ নিষ্কর্ষ নয়, আমরা উভয় ব্যবহার করবে Exif-JS এবং লোড ইমেজ , জাভাস্ক্রিপ্ট লাইব্রেরি তাই প্রথম ফলো যেমন আপনার পৃষ্ঠায় এই লাইব্রেরি যোগ করুন:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/exif-js/2.1.0/exif.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-load-image/2.12.2/load-image.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-load-image/2.12.2/load-image-scale.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-load-image/2.12.2/load-image-orientation.min.js"></script>

    নোট করুন এক্সিফ-জেএসের সংস্করণটির ২.২ এ সমস্যা রয়েছে তাই আমরা ২.১ ব্যবহার করেছি

  2. তাহলে মূলত আমরা যা করব তা হ'ল

    একটি - ব্যবহার করে ইমেজ লোড করুন window.loadImage()

    খ - এক্সিফ ট্যাগ ব্যবহার করে পড়ুন window.EXIF.getData()

    সি - চিত্রটি ক্যানভাসে রূপান্তর করুন এবং ব্যবহার করে চিত্রের ওরিয়েন্টেশনটি ঠিক করুন window.loadImage.scale()

    d - নথিতে ক্যানভাস রাখুন

আপনি এখানে যান :)

window.loadImage("/your-image.jpg", function (img) {
  if (img.type === "error") {
    console.log("couldn't load image:", img);
  } else {
    window.EXIF.getData(img, function () {
        var orientation = EXIF.getTag(this, "Orientation");
        var canvas = window.loadImage.scale(img, {orientation: orientation || 0, canvas: true});
        document.getElementById("container").appendChild(canvas); 
        // or using jquery $("#container").append(canvas);

    });
  }
});

অবশ্যই আপনি ক্যানভাস অবজেক্ট থেকে ইমেজটি বেস 64 হিসাবে পেতে এবং এটি img src অ্যাট্রিবিউটে রাখতে পারেন, তাই jQuery ব্যবহার করে আপনি যা করতে পারেন;)

$("#my-image").attr("src",canvas.toDataURL());

এখানে সম্পূর্ণ কোডটি এখানে রয়েছে: গিথুব: https://github.com/digital-flowers/loadimage-exif-example


সমাধান 2: এইচটিএমএল ব্যবহার করে (ব্রাউজার হ্যাক)

একটি খুব দ্রুত এবং সহজ হ্যাক রয়েছে, বেশিরভাগ ব্রাউজারগুলি চিত্রটি কোনও সঠিক এইচটিএমএল ছাড়াই কোনও নতুন ট্যাবটির ভিতরে খোলা থাকলে ডান দিকনির্দেশে চিত্রটি প্রদর্শন করে (এলএল আমি কেন জানি না), তাই মূলত আপনি ইফ্রেমে ব্যবহার করে আপনার চিত্রটি প্রদর্শন করতে পারেন চিত্রের url হিসাবে সরাসরি iframe src বৈশিষ্ট্যটি রেখে:

<iframe src="/my-image.jpg"></iframe>

সমাধান 3: সিএসএস ব্যবহার করে (কেবলমাত্র ফায়ারফক্স এবং আইওএসে সাফারি)

ইমেজ ওরিয়েন্টেশন ঠিক করার জন্য সিএসএস 3 বৈশিষ্ট্য রয়েছে তবে সমস্যাটি এটি কেবল ফায়ারফক্স এবং সাফারি / আইওএস নিয়ে কাজ করছে এটি এখনও উল্লেখযোগ্য কারণ এটি শীঘ্রই এটি সমস্ত ব্রাউজারের জন্য উপলব্ধ হবে ( ক্যানিউজ থেকে ব্রাউজার সমর্থন তথ্য )

img {
   image-orientation: from-image;
}

সমাধান 1 আমার পক্ষে কাজ করে নি। এটি উইন্ডোতে ফিরছে loadলোড চিত্রটি পূর্বনির্ধারিত
পেরি

আপনি যদি প্রথম ধাপে উল্লিখিত লাইব্রেরিগুলি অন্তর্ভুক্ত না করেন তবে এটি ঘটেছিল
ফরিদ অ্যালামনোউটি

আমি লাইব্রেরি অন্তর্ভুক্ত। আমি আপনার উদাহরণের সরলতা পছন্দ করি তবে আমি ত্রুটি বার্তাটি পেয়ে যাচ্ছি।
পেরি

1
দেখে মনে হচ্ছে এক্সিফ-জেএসটি ভেঙে গেছে, দয়া করে আমার সম্পাদনা পরীক্ষা করুন আমি গিথুব
ফারিদ অ্যালামনোউটি

1
ঠিক আছে, গিথুব প্রকল্পটি চেকআউট করুন একটি নতুন ফাইল "আপলোডচিটএমএল" আছে, আপনাকে স্বাগতম! :)
ফরিদ অ্যালামনোউটি

10

যাঁরা একটি ইনপুট নিয়ন্ত্রণ থেকে ফাইল পেয়েছেন, জানেন না যে এর অরিয়েন্টেশনটি কী, কিছুটা অলস এবং নীচে একটি বড় লাইব্রেরি অন্তর্ভুক্ত করতে চান না তিনি @ ওয়ান্ডার বার্টের দেওয়া উত্তরটি দিয়ে মিলিত কোডটি দেওয়া হয়েছে ( https://stackoverflow.com/a/32490603 ) যা ওরিয়েন্টেশন খুঁজে পায়।

function getDataUrl(file, callback2) {
        var callback = function (srcOrientation) {
            var reader2 = new FileReader();
            reader2.onload = function (e) {
                var srcBase64 = e.target.result;
                var img = new Image();

                img.onload = function () {
                    var width = img.width,
                        height = img.height,
                        canvas = document.createElement('canvas'),
                        ctx = canvas.getContext("2d");

                    // set proper canvas dimensions before transform & export
                    if (4 < srcOrientation && srcOrientation < 9) {
                        canvas.width = height;
                        canvas.height = width;
                    } else {
                        canvas.width = width;
                        canvas.height = height;
                    }

                    // transform context before drawing image
                    switch (srcOrientation) {
                        case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
                        case 3: ctx.transform(-1, 0, 0, -1, width, height); break;
                        case 4: ctx.transform(1, 0, 0, -1, 0, height); break;
                        case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
                        case 6: ctx.transform(0, 1, -1, 0, height, 0); break;
                        case 7: ctx.transform(0, -1, -1, 0, height, width); break;
                        case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
                        default: break;
                    }

                    // draw image
                    ctx.drawImage(img, 0, 0);

                    // export base64
                    callback2(canvas.toDataURL());
                };

                img.src = srcBase64;
            }

            reader2.readAsDataURL(file);
        }

        var reader = new FileReader();
        reader.onload = function (e) {

            var view = new DataView(e.target.result);
            if (view.getUint16(0, false) != 0xFFD8) return callback(-2);
            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) return callback(-1);
                    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)
                            return callback(view.getUint16(offset + (i * 12) + 8, little));
                }
                else if ((marker & 0xFF00) != 0xFF00) break;
                else offset += view.getUint16(offset, false);
            }
            return callback(-1);
        };
        reader.readAsArrayBuffer(file);
    }

যা সহজেই এর মতো বলা যেতে পারে

getDataUrl(input.files[0], function (imgBase64) {
      vm.user.BioPhoto = imgBase64;
});

2
গুগল দ্বারা 2 ঘন্টার বেশি অনুসন্ধানের পরে ধন্যবাদ আমি সঠিক সমাধানটি পেয়েছি।
মিঃ ট্রিইউ

2
কেন কেউ বেশি হালকা সমাধান পছন্দ করতে অলস হবে?
শিশির

4
টাইপস্ক্রিপ্টে পোর্ট করা হয়েছে এবং প্রায় 4 সেকেন্ড থেকে ~ 20 মিলিসেকেন্ডে অনুকূলিত হয়েছে। বেস 64 এর এনকোডিংটি ছিল বাধা - image/jpegডিফল্টের পরিবর্তে ব্যবহার করা image/pngএবং আউটপুট চিত্রকে সর্বোচ্চ প্রস্থে (আমার ক্ষেত্রে 400px) আকার দেওয়ার ফলে ব্যাপক পার্থক্য হয়েছিল। (এটি থাম্বনেইলগুলির জন্য ভাল কাজ করে, তবে আপনাকে যদি পুরো চিত্রটি প্রদর্শন করতে হয় তবে আমি বেস 64 এড়ানো এবং ক্যানভাস উপাদানটি সরাসরি পৃষ্ঠায় ইনজেক্ট করার পরামর্শ দেব ...)
mindplay.dk

8

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

ওয়ান্ডারবার্ট থেকে সমস্ত তথ্য একসাথে রাখা, এরকম কিছু;

var handleTakePhoto = function () {
    let fileInput: HTMLInputElement = <HTMLInputElement>document.getElementById('photoInput');
    fileInput.addEventListener('change', (e: any) => handleInputUpdated(fileInput, e.target.files));
    fileInput.click();
}

var handleInputUpdated = function (fileInput: HTMLInputElement, fileList) {
    let file = null;

    if (fileList.length > 0 && fileList[0].type.match(/^image\//)) {
        isLoading(true);
        file = fileList[0];
        getOrientation(file, function (orientation) {
            if (orientation == 1) {
                imageBinary(URL.createObjectURL(file));
                isLoading(false);
            }
            else 
            {
                resetOrientation(URL.createObjectURL(file), orientation, function (resetBase64Image) {
                    imageBinary(resetBase64Image);
                    isLoading(false);
                });
            }
        });
    }

    fileInput.removeEventListener('change');
}


// from http://stackoverflow.com/a/32490603
export function getOrientation(file, callback) {
    var reader = new FileReader();

    reader.onload = function (event: any) {
        var view = new DataView(event.target.result);

        if (view.getUint16(0, false) != 0xFFD8) return callback(-2);

        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) {
                    return callback(-1);
                }
                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)
                        return callback(view.getUint16(offset + (i * 12) + 8, little));
            }
            else if ((marker & 0xFF00) != 0xFF00) break;
            else offset += view.getUint16(offset, false);
        }
        return callback(-1);
    };

    reader.readAsArrayBuffer(file.slice(0, 64 * 1024));
};

export function resetOrientation(srcBase64, srcOrientation, callback) {
    var img = new Image();

    img.onload = function () {
        var width = img.width,
            height = img.height,
            canvas = document.createElement('canvas'),
            ctx = canvas.getContext("2d");

        // set proper canvas dimensions before transform & export
        if (4 < srcOrientation && srcOrientation < 9) {
            canvas.width = height;
            canvas.height = width;
        } else {
            canvas.width = width;
            canvas.height = height;
        }

        // transform context before drawing image
        switch (srcOrientation) {
            case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
            case 3: ctx.transform(-1, 0, 0, -1, width, height); break;
            case 4: ctx.transform(1, 0, 0, -1, 0, height); break;
            case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
            case 6: ctx.transform(0, 1, -1, 0, height, 0); break;
            case 7: ctx.transform(0, -1, -1, 0, height, width); break;
            case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
            default: break;
        }

        // draw image
        ctx.drawImage(img, 0, 0);

        // export base64
        callback(canvas.toDataURL());
    };

    img.src = srcBase64;
}

1
দুর্দান্ত পন্থা। এছাড়াও আপনি হ্যান্ডলিং বিবেচনা করা উচিত -2এবং -1থেকে ফেরত getOrientationযাতে আপনি ঘূর্ণন ডেটা ছাড়া ঘোরান অ jpgs বা ছবি চেষ্টা করবেন না।
স্টিভেন ল্যামবার্ট

আমি আরও অনুকূলিতকরণ করেছি, উপরে আমার মন্তব্য দেখুন - আমি আপনার file.slice()অপ্টিমাইজেশনটিও যুক্ত করেছি, তবে আসল উত্সাহটি image/jpegছোট ডেটা ইউআরএল তৈরি করতে ছোট চিত্র এবং আউটপুট ফর্ম্যাট ব্যবহার করে আসে । (10-মেগাপিক্সেল চিত্রের জন্যও কোনও লক্ষণীয় বিলম্ব নেই))
mindplay.dk

সাবধান file.slice(), যেমন আপনি বেস 64 ইমেজ উত্স সমর্থন প্রতিরোধ করবে।
চিহ্নিত করুন

ধন্যবাদ চিহ্ন - একটি বিকল্পের জন্য একটি সম্পাদনা প্রদান যত্ন?
স্ট্যাটার

7

এক লাইনার কেউ?

আমি কাউকে browser-image-compressionলাইব্রেরির উল্লেখ করতে দেখিনি । এটি এর জন্য নিখুঁতভাবে একটি সহায়ক ফাংশন পেয়েছে।

ব্যবহার: const orientation = await imageCompression.getExifOrientation(file)

অন্যান্য অনেক উপায়েও এ জাতীয় দরকারী সরঞ্জাম।


এটি ওরিয়েন্টেশন পায়। তবে কীভাবে আমি এই তথ্য ব্যবহার করে ক্লায়েন্টের পাশে নতুন .jpg ফাইল অবজেক্ট তৈরি করব?
মাস্টারেক্সিলো

Fileআমি যতদূর জানি আপনি অবজেক্ট তৈরি করতে পারবেন না । পরের সেরাটি হ'ল ইমেজ এবং ওরিয়েন্টেশনটি সার্ভারে প্রেরণ করা এবং সেখানে ফাইল ম্যানিপুলেশন করা। অথবা আপনি ব্যবহার করে একটি বেস 64 স্ট্রিং canvasএবং toDataURLপদ্ধতিটি তৈরি করতে পারেন ।
গিলবার্ট-ভি

1
না আপনি ব্লব থেকে কোনও ফাইল অবজেক্ট তৈরি করতে পারবেন না ঠিক আছে। ফাইল ফাইল (অ্যারে পার্টস, স্ট্রিং ফাইলের নাম, ব্লবপ্রপার্টিব্যাগ বৈশিষ্ট্য); বিকাশকারী.মোজিলা.আর.ডগ
ডকস

2
সোনার স্টিকার! @ মাস্টারেক্সিলো
গিলবার্ট-ভি

2
এটি আমার জন্য কাজ করে মহান! আমি গত 2 দিন ধরে ওরিয়েন্টেশন নিয়ে লড়াই করে যাচ্ছিলাম! পোস্ট করা সমস্ত ট্রান্সফর্ম স্যুইচ স্টেটমেন্টগুলি কোনও কারণে আমার ফোন থেকে প্রতিকৃতি চিত্রগুলি পরিচালনা করবে না, সেখানে কালো দণ্ড থাকবে। সম্ভবত কারণ আমি একই সময়ে সংকোচনের এবং ঘোরানোর চেষ্টা করছিলাম।
cjd82187

2

আমি ES6 মডিউলটিতে মোড়ানো একটি ক্লাস তৈরি করেছি যা ঠিক এটি সমাধান করে।

এটি 103 টি লাইন, কোনও নির্ভরতা নেই এবং মোটামুটি সুন্দরভাবে কাঠামোযুক্ত ও নথিভুক্ত, যার অর্থ পরিবর্তন / পুনঃব্যবহার করা সহজ হবে।

সমস্ত 8 টি সম্ভাব্য দিকনির্দেশনা পরিচালনা করে এবং এটি প্রতিশ্রুতি ভিত্তিক।

আপনি এখানে যান, আশা করি এটি এখনও কাউকে সহায়তা করে: https://gist.github.com/vdavid/3f9b66b60f52204317a4cc0e77097913


1

আমি মিশ্র সমাধান (পিএইচপি + সিএসএস) ব্যবহার করছি।

ধারকগুলির জন্য প্রয়োজনীয়:

  • div.imgCont2 ঘোরানোর জন্য ধারক প্রয়োজন;
  • div.imgCont1জুমআউট করার জন্য ধারক প্রয়োজন - width:150%;
  • div.imgCont স্ক্রোলবারগুলির জন্য ধারক প্রয়োজন, যখন চিত্রটি জুমআউট হয়।

<?php
    $image_url = 'your image url.jpg';
    $exif = @exif_read_data($image_url,0,true);
    $orientation = @$exif['IFD0']['Orientation'];
?>

<style>
.imgCont{
    width:100%;
    overflow:auto;
}
.imgCont2[data-orientation="8"]{
    transform:rotate(270deg);
    margin:15% 0;
}
.imgCont2[data-orientation="6"]{
    transform:rotate(90deg);
    margin:15% 0;
}
.imgCont2[data-orientation="3"]{
    transform:rotate(180deg);
}
img{
    width:100%;
}
</style>

<div class="imgCont">
  <div class="imgCont1">
    <div class="imgCont2" data-orientation="<?php echo($orientation) ?>">
      <img src="<?php echo($image_url) ?>">
    </div>
  </div>
</div>

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

0

@ ফরেড নম্রউটির উত্তর ছাড়াও,

যদি কোনও ফাইল ইনপুট উপাদান থেকে চিত্রটি ব্রাউজ করতে হয় তবে এটি ব্যবহার করা উচিত

<input type="file" name="file" id="file-input"><br/>
image after transform: <br/>
<div id="container"></div>

<script>
    document.getElementById('file-input').onchange = function (e) {
        var image = e.target.files[0];
        window.loadImage(image, function (img) {
            if (img.type === "error") {
                console.log("couldn't load image:", img);
            } else {
                window.EXIF.getData(image, function () {
                    console.log("load image done!");
                    var orientation = window.EXIF.getTag(this, "Orientation");
                    var canvas = window.loadImage.scale(img,
                        {orientation: orientation || 0, canvas: true, maxWidth: 200});
                    document.getElementById("container").appendChild(canvas);
                    // or using jquery $("#container").append(canvas);
                });
            }
        });
    };
</script>

0

আমি একটু পিএইচপি স্ক্রিপ্ট লিখেছি যা চিত্রটি ঘোরায়। প্রতিটি অনুরোধটিকে কেবল পুনরায় গণনার পক্ষে চিত্রটি সংরক্ষণ করার বিষয়টি নিশ্চিত করুন।

<?php

header("Content-type: image/jpeg");
$img = 'IMG URL';

$exif = @exif_read_data($img,0,true);
$orientation = @$exif['IFD0']['Orientation'];
if($orientation == 7 || $orientation == 8) {
    $degrees = 90;
} elseif($orientation == 5 || $orientation == 6) {
    $degrees = 270;
} elseif($orientation == 3 || $orientation == 4) {
    $degrees = 180;
} else {
    $degrees = 0;
}
$rotate = imagerotate(imagecreatefromjpeg($img), $degrees, 0);
imagejpeg($rotate);
imagedestroy($rotate);

?>

চিয়ার্স

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