পুরো ফাইলটি না পড়ে চিত্রের মাত্রা পাওয়া


104

কোনও চিত্রের মাত্রা (jpg, png, ...) পাওয়ার কোনও সস্তা উপায় নেই? সাধারণত, আমি কেবলমাত্র স্ট্যান্ডার্ড ক্লাসের লাইব্রেরি (হোস্টিং বিধিনিষেধের কারণে) ব্যবহার করে এটি অর্জন করতে চাই। আমি জানি যে চিত্রের শিরোনামটি পড়া এবং এটি নিজেই বিশ্লেষণ করা তুলনামূলকভাবে সহজ হওয়া উচিত, তবে মনে হয় এরকম কিছু ইতিমধ্যে সেখানে থাকা উচিত। এছাড়াও, আমি যাচাই করেছি যে নিম্নলিখিত কোডের টুকরা পুরো চিত্রটি পড়ে (যা আমি চাই না):

using System;
using System.Drawing;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Image img = new Bitmap("test.png");
            System.Console.WriteLine(img.Width + " x " + img.Height);
        }
    }
}

আপনি যদি প্রশ্নটিতে কিছুটা বেশি নির্দিষ্ট হয়ে থাকেন তবে এটি সহায়তা করবে। ট্যাগগুলি আমাকে। নেট এবং সি # বলেছে এবং আপনি স্ট্যান্ডার্ড লাইব্রেরি চান তবে এই হোস্টিং বিধিনিষেধগুলি কী আপনি উল্লেখ করেছেন?
Wnoise

যদি আপনার সিস্টেমে অ্যাক্সেস রয়েছে W উইন্ডোস M মিডিয়া ma ইমেজিং নেমস্পেস (ডাব্লুপিএফ এ), এই এই প্রশ্নটি দেখুন: স্ট্যাকওভারফ্লো
চার্লি

উত্তর:


106

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

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;

namespace ImageDimensions
{
    public static class ImageHelper
    {
        const string errorMessage = "Could not recognize image format.";

        private static Dictionary<byte[], Func<BinaryReader, Size>> imageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, Size>>()
        {
            { new byte[]{ 0x42, 0x4D }, DecodeBitmap},
            { new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif },
            { new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif },
            { new byte[]{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng },
            { new byte[]{ 0xff, 0xd8 }, DecodeJfif },
        };

        /// <summary>
        /// Gets the dimensions of an image.
        /// </summary>
        /// <param name="path">The path of the image to get the dimensions of.</param>
        /// <returns>The dimensions of the specified image.</returns>
        /// <exception cref="ArgumentException">The image was of an unrecognized format.</exception>
        public static Size GetDimensions(string path)
        {
            using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)))
            {
                try
                {
                    return GetDimensions(binaryReader);
                }
                catch (ArgumentException e)
                {
                    if (e.Message.StartsWith(errorMessage))
                    {
                        throw new ArgumentException(errorMessage, "path", e);
                    }
                    else
                    {
                        throw e;
                    }
                }
            }
        }

        /// <summary>
        /// Gets the dimensions of an image.
        /// </summary>
        /// <param name="path">The path of the image to get the dimensions of.</param>
        /// <returns>The dimensions of the specified image.</returns>
        /// <exception cref="ArgumentException">The image was of an unrecognized format.</exception>    
        public static Size GetDimensions(BinaryReader binaryReader)
        {
            int maxMagicBytesLength = imageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length;

            byte[] magicBytes = new byte[maxMagicBytesLength];

            for (int i = 0; i < maxMagicBytesLength; i += 1)
            {
                magicBytes[i] = binaryReader.ReadByte();

                foreach(var kvPair in imageFormatDecoders)
                {
                    if (magicBytes.StartsWith(kvPair.Key))
                    {
                        return kvPair.Value(binaryReader);
                    }
                }
            }

            throw new ArgumentException(errorMessage, "binaryReader");
        }

        private static bool StartsWith(this byte[] thisBytes, byte[] thatBytes)
        {
            for(int i = 0; i < thatBytes.Length; i+= 1)
            {
                if (thisBytes[i] != thatBytes[i])
                {
                    return false;
                }
            }
            return true;
        }

        private static short ReadLittleEndianInt16(this BinaryReader binaryReader)
        {
            byte[] bytes = new byte[sizeof(short)];
            for (int i = 0; i < sizeof(short); i += 1)
            {
                bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte();
            }
            return BitConverter.ToInt16(bytes, 0);
        }

        private static int ReadLittleEndianInt32(this BinaryReader binaryReader)
        {
            byte[] bytes = new byte[sizeof(int)];
            for (int i = 0; i < sizeof(int); i += 1)
            {
                bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte();
            }
            return BitConverter.ToInt32(bytes, 0);
        }

        private static Size DecodeBitmap(BinaryReader binaryReader)
        {
            binaryReader.ReadBytes(16);
            int width = binaryReader.ReadInt32();
            int height = binaryReader.ReadInt32();
            return new Size(width, height);
        }

        private static Size DecodeGif(BinaryReader binaryReader)
        {
            int width = binaryReader.ReadInt16();
            int height = binaryReader.ReadInt16();
            return new Size(width, height);
        }

        private static Size DecodePng(BinaryReader binaryReader)
        {
            binaryReader.ReadBytes(8);
            int width = binaryReader.ReadLittleEndianInt32();
            int height = binaryReader.ReadLittleEndianInt32();
            return new Size(width, height);
        }

        private static Size DecodeJfif(BinaryReader binaryReader)
        {
            while (binaryReader.ReadByte() == 0xff)
            {
                byte marker = binaryReader.ReadByte();
                short chunkLength = binaryReader.ReadLittleEndianInt16();

                if (marker == 0xc0)
                {
                    binaryReader.ReadByte();

                    int height = binaryReader.ReadLittleEndianInt16();
                    int width = binaryReader.ReadLittleEndianInt16();
                    return new Size(width, height);
                }

                binaryReader.ReadBytes(chunkLength - 2);
            }

            throw new ArgumentException(errorMessage);
        }
    }
}

আশা করি কোডটি মোটামুটি সুস্পষ্ট। একটি নতুন ফাইল ফর্ম্যাট যুক্ত করতে আপনি এটিকে imageFormatDecoders"ম্যাজিক বিট" এর অ্যারে হিসাবে কী যুক্ত করেছেন যা প্রদত্ত ফর্ম্যাটটির প্রতিটি ফাইলের শুরুতে প্রদর্শিত হবে এবং মানটি একটি ফাংশন যা প্রবাহ থেকে আকারটি বের করে। বেশিরভাগ ফর্ম্যাটগুলি যথেষ্ট সহজ, একমাত্র আসল দুর্গন্ধ jpeg।


6
রাজি হয়েছে, জেপিইজি সফল হয়েছে। বিটিডব্লিউ - এমন লোকদের জন্য একটি নোট যা ভবিষ্যতে এই কোডটি ব্যবহার করতে চায়: এটি সত্যই অনির্ধারিত। আমি একটি সূক্ষ্ম চিরুনি দিয়ে এটি পেরিয়েছি, এবং যা আমি পেয়েছি তা এখানেই রয়েছে: বিএমপি ফর্ম্যাটে আরও একটি (প্রাচীন) শিরোনামের প্রকরণ রয়েছে যেখানে মাত্রা 16-বিট; প্লাস উচ্চতা নেতিবাচক হতে পারে (তারপরে সাইনটি ড্রপ করুন)। JPEG - 0xC0 হিসাবে একমাত্র শিরোনাম নয়। মূলত 0xC4 এবং 0xCF ব্যতীত 0xC0 থেকে 0xCF এর সমস্তগুলি বৈধ শিরোনাম (আপনি সহজেই এগুলি ইন্টারলেসড জেপিজিতে পেতে পারেন)। এবং, জিনিসগুলিকে আরও মজাদার করতে উচ্চতা 0 হতে পারে এবং পরে 0 এক্সডিসি ব্লকে নির্দিষ্ট করা যেতে পারে। W3.org/ গ্রাফিক্স
বিউটিউইটি

আসল (চিহ্নিতকারী == 0xC0) 0xC1 এবং 0xC2 গ্রহণ করার জন্য চেকটিও প্রসারিত করতে উপরের ডিকোডজেফিফ পদ্ধতিটি টিক্ক করে। এই অন্যান্য স্টার্ট-অফ ফ্রেম শিরোনামগুলি এসওএফ 1 এবং এসওএফ 2 একই বাইট অবস্থানগুলিতে প্রস্থ / উচ্চতা এনকোড করে। এসওএফ 2 মোটামুটি সাধারণ।
রায়ান বার্টন

4
স্ট্যান্ডার্ড সতর্কতা: আপনার পরিবর্তে throw e;কেবল লেখা উচিত নয় throw;। তোমার সেকেন্ড এক্সএমএল ডক মন্তব্য GetDimensionsদেখাতে pathপরিবর্তেbinaryReader
Eregrith

1
এছাড়াও, মনে হচ্ছে এই কোডটি এক্সিএফ / টিআইএফএফ ফর্ম্যাটে এনকোডযুক্ত জেপিগগুলি গ্রহণ করে না যা অনেকগুলি ডিজিটাল ক্যামেরায় আউটপুট। এটি কেবল জেএফআইএফ সমর্থন করে।
cwills 1'18

2
সিস্টেম.ড্রেইং.ইমজ.ফ্রিম স্ট্রিম (স্ট্রিম, ভুয়া, মিথ্যা) আপনাকে পুরো চিত্রটি লোড না করেই মাত্রা দেবে এবং এটি কোনও চিত্রে কাজ করে। নেট লোড করতে পারে। এই অগোছালো এবং অসম্পূর্ণ সমাধানটিতে কেন অনেক উত্সাহ রয়েছে তা বোঝার বাইরে।
ডায়নামিকেল

25
using (FileStream file = new FileStream(this.ImageFileName, FileMode.Open, FileAccess.Read))
{
    using (Image tif = Image.FromStream(stream: file, 
                                        useEmbeddedColorManagement: false,
                                        validateImageData: false))
    {
        float width = tif.PhysicalDimension.Width;
        float height = tif.PhysicalDimension.Height;
        float hresolution = tif.HorizontalResolution;
        float vresolution = tif.VerticalResolution;
     }
}

validateImageDataসেট false, ইমেজ ডেটার ব্যয়বহুল বিশ্লেষণ পারফর্মিং এইভাবে গুরুতরভাবে লোড সময় কমে থেকে আটকায় GDI এর + +। এই প্রশ্নটি বিষয়টিতে আরও আলোকপাত করে।


1
আমি উপরের আইসিআরের সমাধানের সাথে মিশ্রিত সর্বশেষ সংস্থান হিসাবে আপনার সমাধানটি ব্যবহার করেছি। জেপিজি নিয়ে সমস্যা ছিল এবং এটি দিয়ে সমাধান করা হয়েছে।
জোরকিন্দ

2
আমি সম্প্রতি এমন একটি প্রকল্পে এটি চেষ্টা করেছি যেখানে আমাকে 2000+ চিত্রের আকার (জেপিজি এবং পিএনজি বেশিরভাগ ক্ষেত্রেই খুব মিশ্রিত আকার) জিজ্ঞাসা করতে হয়েছিল, এবং এটি ব্যবহারের প্রচলিত পদ্ধতির চেয়ে সত্যই দ্রুত ছিল new Bitmap()
AeonOfTime

1
সর্বোত্তম উত্তর. দ্রুত, পরিষ্কার এবং কার্যকর।
ডায়নামিকেল

1
এই ফাংশনটি উইন্ডোতে নিখুঁত। তবে এটি লিনাক্সে কাজ করছে না, এটি এখনও লিনাক্সে পুরো ফাইলটি পড়বে। (। নেট কোর 2.2)
ঝেংচুন

21

আপনি কি ডাব্লুপিএফ ইমেজিং ক্লাস ব্যবহার করার চেষ্টা করেছেন? System.Windows.Media.Imaging.BitmapDecoder, ইত্যাদি?

আমি বিশ্বাস করি যে হেডারের তথ্য নির্ধারণের জন্য এই কোডেকগুলি কেবল ফাইলের একটি উপসেটটি পড়েছে তা নিশ্চিত করার চেষ্টা করেছিল। এটি একটি চেক মূল্য।


ধন্যবাদ. যুক্তিযুক্ত বলে মনে হয়, কিন্তু আমার হোস্টিং .NET 2. হয়েছে
জানুয়ারী Zich

1
দুর্দান্ত উত্তর। আপনি যদি আপনার প্রকল্পের প্রেজেন্টেশন কোরের একটি রেফারেন্স পেতে পারেন তবে এটি যাওয়ার উপায়।
ojrac

আমার ইউনিট পরীক্ষায়, এই ক্লাসগুলি জিডিআই এর চেয়ে ভাল কোনও পারফরম্যান্স করে না ... এখনও জেপিইজি মাত্রা পড়তে ~ 32K প্রয়োজন।
নরিমন

সুতরাং ওপি'র চিত্রের মাত্রা পেতে আপনি কীভাবে বিটম্যাপডেকোডার ব্যবহার করবেন?
চক সেভেজ

1
এই এই প্রশ্নটি দেখুন: স্ট্যাকওভারফ্লো.com
চার্লি

12

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

ভাগ্যক্রমে জিআইএফের ক্ষেত্রে, সমস্ত প্রয়োজনীয় তথ্য প্রথম 10 বাইটে ছিল:

Type: Bytes 0-2
Version: Bytes 3-5
Height: Bytes 6-7
Width: Bytes 8-9

পিএনজি কিছুটা জটিল (প্রস্থ এবং উচ্চতা প্রতিটি 4-বাইট):

Width: Bytes 16-19
Height: Bytes 20-23

উপরে উল্লিখিত হিসাবে, ওয়াটসিট ইমেজ এবং ডেটা ফর্ম্যাটগুলিতে বিশদ চশমাগুলির জন্য একটি ভাল সাইট যদিও পিএনজি্লিবের পিএনজি স্পেসগুলি আরও বিস্তারিত are তবে আমি মনে করি পিএনজি এবং জিআইএফ ফর্ম্যাটে উইকিপিডিয়া এন্ট্রি শুরু করার সেরা জায়গা।

জিআইএফ চেক করার জন্য আমার আসল কোডটি এখানে, পিএনজির জন্য আমিও কিছু চড় করেছি:

using System;
using System.IO;
using System.Text;

public class ImageSizeTest
{
    public static void Main()
    {
        byte[] bytes = new byte[10];

        string gifFile = @"D:\Personal\Images&Pics\iProduct.gif";
        using (FileStream fs = File.OpenRead(gifFile))
        {
            fs.Read(bytes, 0, 10); // type (3 bytes), version (3 bytes), width (2 bytes), height (2 bytes)
        }
        displayGifInfo(bytes);

        string pngFile = @"D:\Personal\Images&Pics\WaveletsGamma.png";
        using (FileStream fs = File.OpenRead(pngFile))
        {
            fs.Seek(16, SeekOrigin.Begin); // jump to the 16th byte where width and height information is stored
            fs.Read(bytes, 0, 8); // width (4 bytes), height (4 bytes)
        }
        displayPngInfo(bytes);
    }

    public static void displayGifInfo(byte[] bytes)
    {
        string type = Encoding.ASCII.GetString(bytes, 0, 3);
        string version = Encoding.ASCII.GetString(bytes, 3, 3);

        int width = bytes[6] | bytes[7] << 8; // byte 6 and 7 contain the width but in network byte order so byte 7 has to be left-shifted 8 places and bit-masked to byte 6
        int height = bytes[8] | bytes[9] << 8; // same for height

        Console.WriteLine("GIF\nType: {0}\nVersion: {1}\nWidth: {2}\nHeight: {3}\n", type, version, width, height);
    }

    public static void displayPngInfo(byte[] bytes)
    {
        int width = 0, height = 0;

        for (int i = 0; i <= 3; i++)
        {
            width = bytes[i] | width << 8;
            height = bytes[i + 4] | height << 8;            
        }

        Console.WriteLine("PNG\nWidth: {0}\nHeight: {1}\n", width, height);  
    }
}

8

এখনও অবধি উত্তর এবং কিছু অতিরিক্ত অনুসন্ধানের ভিত্তিতে মনে হয় যে .NET 2 শ্রেণির লাইব্রেরিতে এটির জন্য কোনও কার্যকারিতা নেই। তাই আমি নিজের লেখার সিদ্ধান্ত নিয়েছি। এটির একটি খুব রুক্ষ সংস্করণ এখানে। এই মুহুর্তে, আমার এটি কেবল জেপিজির জন্য প্রয়োজন। সুতরাং এটি আব্বাসের পোস্ট করা উত্তর সম্পূর্ণ করে।

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

using System;
using System.IO;

namespace Test
{

    class Program
    {

        static bool GetJpegDimension(
            string fileName,
            out int width,
            out int height)
        {

            width = height = 0;
            bool found = false;
            bool eof = false;

            FileStream stream = new FileStream(
                fileName,
                FileMode.Open,
                FileAccess.Read);

            BinaryReader reader = new BinaryReader(stream);

            while (!found || eof)
            {

                // read 0xFF and the type
                reader.ReadByte();
                byte type = reader.ReadByte();

                // get length
                int len = 0;
                switch (type)
                {
                    // start and end of the image
                    case 0xD8: 
                    case 0xD9: 
                        len = 0;
                        break;

                    // restart interval
                    case 0xDD: 
                        len = 2;
                        break;

                    // the next two bytes is the length
                    default: 
                        int lenHi = reader.ReadByte();
                        int lenLo = reader.ReadByte();
                        len = (lenHi << 8 | lenLo) - 2;
                        break;
                }

                // EOF?
                if (type == 0xD9)
                    eof = true;

                // process the data
                if (len > 0)
                {

                    // read the data
                    byte[] data = reader.ReadBytes(len);

                    // this is what we are looking for
                    if (type == 0xC0)
                    {
                        width = data[1] << 8 | data[2];
                        height = data[3] << 8 | data[4];
                        found = true;
                    }

                }

            }

            reader.Close();
            stream.Close();

            return found;

        }

        static void Main(string[] args)
        {
            foreach (string file in Directory.GetFiles(args[0]))
            {
                int w, h;
                GetJpegDimension(file, out w, out h);
                System.Console.WriteLine(file + ": " + w + " x " + h);
            }
        }

    }
}

যখন আমি এটি চেষ্টা করি তখন প্রস্থ এবং উচ্চতা বিপরীত হয়।
জেসন স্ট্রেজস

@ জেসনস্টর্জেস এজিফ ওরিয়েন্টেশন ট্যাগটি আপনার বিবেচনায় নিতে পারে।
অ্যান্ড্রু মর্টন

3

আমি পিএনজি ফাইলের জন্য এটি করেছি

  var buff = new byte[32];
        using (var d =  File.OpenRead(file))
        {            
            d.Read(buff, 0, 32);
        }
        const int wOff = 16;
        const int hOff = 20;            
        var Widht =BitConverter.ToInt32(new[] {buff[wOff + 3], buff[wOff + 2], buff[wOff + 1], buff[wOff + 0],},0);
        var Height =BitConverter.ToInt32(new[] {buff[hOff + 3], buff[hOff + 2], buff[hOff + 1], buff[hOff + 0],},0);

1

হ্যাঁ, আপনি একেবারে এটি করতে পারেন এবং কোড ফাইলের ফর্ম্যাটের উপর নির্ভর করে। আমি একটি ইমেজিং বিক্রেতার ( অ্যাটালসফট ) জন্য কাজ করি এবং আমাদের পণ্যটি প্রতিটি কোডেকের জন্য একটি গেটমিজেনআইএনফো () সরবরাহ করে যা মাত্রা খুঁজে বের করার জন্য ন্যূনতম এবং ডেটা পেতে সহজেই কিছু সহজ করে তোলে।

আপনি যদি নিজের নিজস্ব রোল করতে চান তবে আমি wotsit.org দিয়ে শুরু করার পরামর্শ দিচ্ছি , যা সমস্ত চিত্রের ফর্ম্যাটগুলির জন্য বিশদ চশমা রয়েছে এবং আপনি ফাইলটি কীভাবে চিহ্নিত করতে পারবেন এবং এটিতে তথ্য কোথায় পাওয়া যাবে তাও দেখতে পাবেন।

আপনি যদি সি এর সাথে কাজ করতে স্বাচ্ছন্দ্য বোধ করেন তবে ফ্রি জেপিগ্লিবও এই তথ্যটি পেতে ব্যবহার করা যেতে পারে। আমি বাজি ধরব যে আপনি নেট নেট লাইব্রেরি দিয়ে এটি করতে পারেন, তবে আমি জানি না।


এটা নিরাপদ যে ধরে নেওয়া নিরাপদ যে ব্যবহার new AtalaImage(filepath).Widthকরে কিছু অনুরূপ আছে?
ড্রজাউস


1
প্রথম (অ্যাটালাইমেজ) পুরো চিত্রটি পড়ে - দ্বিতীয় (গেটআইজেজইনফো) কোনও চিত্র তথ্য অবজেক্টের উপাদানগুলি পেতে সর্বনিম্ন মেটাডেটা পড়ে।
লু ফ্রাঙ্কো

0

প্রগতিশীল জেপেসস এবং ওয়েবপিকে সমর্থন করার জন্য আইসিআরের উত্তর আপডেট করেছে :)

internal static class ImageHelper
{
    const string errorMessage = "Could not recognise image format.";

    private static Dictionary<byte[], Func<BinaryReader, Size>> imageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, Size>>()
    {
        { new byte[] { 0x42, 0x4D }, DecodeBitmap },
        { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif },
        { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif },
        { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng },
        { new byte[] { 0xff, 0xd8 }, DecodeJfif },
        { new byte[] { 0x52, 0x49, 0x46, 0x46 }, DecodeWebP },
    };

    /// <summary>        
    /// Gets the dimensions of an image.        
    /// </summary>        
    /// <param name="path">The path of the image to get the dimensions of.</param>        
    /// <returns>The dimensions of the specified image.</returns>        
    /// <exception cref="ArgumentException">The image was of an unrecognised format.</exception>            
    public static Size GetDimensions(BinaryReader binaryReader)
    {
        int maxMagicBytesLength = imageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length;
        byte[] magicBytes = new byte[maxMagicBytesLength];
        for(int i = 0; i < maxMagicBytesLength; i += 1)
        {
            magicBytes[i] = binaryReader.ReadByte();
            foreach(var kvPair in imageFormatDecoders)
            {
                if(StartsWith(magicBytes, kvPair.Key))
                {
                    return kvPair.Value(binaryReader);
                }
            }
        }

        throw new ArgumentException(errorMessage, "binaryReader");
    }

    private static bool StartsWith(byte[] thisBytes, byte[] thatBytes)
    {
        for(int i = 0; i < thatBytes.Length; i += 1)
        {
            if(thisBytes[i] != thatBytes[i])
            {
                return false;
            }
        }

        return true;
    }

    private static short ReadLittleEndianInt16(BinaryReader binaryReader)
    {
        byte[] bytes = new byte[sizeof(short)];

        for(int i = 0; i < sizeof(short); i += 1)
        {
            bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte();
        }
        return BitConverter.ToInt16(bytes, 0);
    }

    private static int ReadLittleEndianInt32(BinaryReader binaryReader)
    {
        byte[] bytes = new byte[sizeof(int)];
        for(int i = 0; i < sizeof(int); i += 1)
        {
            bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte();
        }
        return BitConverter.ToInt32(bytes, 0);
    }

    private static Size DecodeBitmap(BinaryReader binaryReader)
    {
        binaryReader.ReadBytes(16);
        int width = binaryReader.ReadInt32();
        int height = binaryReader.ReadInt32();
        return new Size(width, height);
    }

    private static Size DecodeGif(BinaryReader binaryReader)
    {
        int width = binaryReader.ReadInt16();
        int height = binaryReader.ReadInt16();
        return new Size(width, height);
    }

    private static Size DecodePng(BinaryReader binaryReader)
    {
        binaryReader.ReadBytes(8);
        int width = ReadLittleEndianInt32(binaryReader);
        int height = ReadLittleEndianInt32(binaryReader);
        return new Size(width, height);
    }

    private static Size DecodeJfif(BinaryReader binaryReader)
    {
        while(binaryReader.ReadByte() == 0xff)
        {
            byte marker = binaryReader.ReadByte();
            short chunkLength = ReadLittleEndianInt16(binaryReader);
            if(marker == 0xc0 || marker == 0xc2) // c2: progressive
            {
                binaryReader.ReadByte();
                int height = ReadLittleEndianInt16(binaryReader);
                int width = ReadLittleEndianInt16(binaryReader);
                return new Size(width, height);
            }

            if(chunkLength < 0)
            {
                ushort uchunkLength = (ushort)chunkLength;
                binaryReader.ReadBytes(uchunkLength - 2);
            }
            else
            {
                binaryReader.ReadBytes(chunkLength - 2);
            }
        }

        throw new ArgumentException(errorMessage);
    }

    private static Size DecodeWebP(BinaryReader binaryReader)
    {
        binaryReader.ReadUInt32(); // Size
        binaryReader.ReadBytes(15); // WEBP, VP8 + more
        binaryReader.ReadBytes(3); // SYNC

        var width = binaryReader.ReadUInt16() & 0b00_11111111111111; // 14 bits width
        var height = binaryReader.ReadUInt16() & 0b00_11111111111111; // 14 bits height

        return new Size(width, height);
    }

}

-1

এটি ফাইল ফর্ম্যাট উপর নির্ভর করতে চলেছে। সাধারণত তারা এটি ফাইলের প্রথম বাইটে প্রকাশ করবে। এবং, সাধারণত, একটি ভাল চিত্র-পঠন বাস্তবায়ন এটি বিবেচনায় নেবে। .NET এর জন্য আমি আপনাকে একটিতে নির্দেশ করতে পারি না।

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