একটি বিটম্যাপটিকে বাইট অ্যারেতে রূপান্তর করুন


233

সি শার্প ব্যবহার করে, সেখানে উইন্ডোজ রূপান্তর করতে একটি ভাল উপায় নেই Bitmapএকটি থেকে byte[]একটি অস্থায়ী ফাইল সংরক্ষণ এবং ব্যবহার ফলাফলের পড়া চেয়ে FileStream?

উত্তর:


418

কয়েকটি উপায় আছে।

ImageConverter

public static byte[] ImageToByte(Image img)
{
    ImageConverter converter = new ImageConverter();
    return (byte[])converter.ConvertTo(img, typeof(byte[]));
}

এটি একা সুবিধাজনক কারণ এর জন্য প্রচুর কোডের প্রয়োজন হয় না।

মেমরি স্ট্রিম

public static byte[] ImageToByte2(Image img)
{
    using (var stream = new MemoryStream())
    {
        img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
        return stream.ToArray();
    }
}

ফাইলটি ডিস্কের পরিবর্তে মেমরিতে সংরক্ষণ করা ছাড়া এটি আপনি যা করছেন তার সমতুল্য। যদিও আরও কোড আপনার কাছে ইমেজ ফর্ম্যাট করার বিকল্প রয়েছে এবং এটি মেমরি বা ডিস্কে সংরক্ষণের মধ্যে সহজেই সংশোধন করা যেতে পারে।

সূত্র: http://www.vcskicks.com/image-to-byte.php


2
এছাড়াও আপনি একটি সহজ জন্য bitmap.Lockbits এবং Marshal.Copy ব্যবহার করতে পারেন ফাস্ট কোনো অন্তর্বর্তী memorystreams ইত্যাদি ছাড়া কপি
deegee

4
দয়া করে সচেতন হন যে ImageConverterপদ্ধতিটি Png হিসাবে চিত্রটি সংরক্ষণ করবে, যার ফলে বিশাল ফাইল।
স্কোলিমা

8
'ব্যবহার' করার সময় আপনাকে স্ট্রিমটি বন্ধ করতে হবে না
লাস্টট্রিবুনাল

2
এই অ্যারেটি কীভাবে কাঠামোবদ্ধ করা হয়েছে সে সম্পর্কে কেউ আমাকে আরও কিছু তথ্য দিতে পারেন? এটি কি x = 0 এবং প্রতিটি y এর মধ্য দিয়ে চক্র এবং তারপরে এক্স বৃদ্ধি করে শুরু হয়? এবং তারপরে এটি স্টোর করুন: [0,0,1,1,1,1,0,0,1,1]?
রেমন্ড টিমারম্যানস

1
ImageConverterআপনি যে নেট মান ব্যবহার করতে পারেন তা নয়MemoryStream
আলেকজান্দ্রে

95

একটি মেমরিস্ট্রিম এটির জন্য সহায়ক হতে পারে। আপনি এটি একটি এক্সটেনশন পদ্ধতিতে রাখতে পারেন:

public static class ImageExtensions
{
    public static byte[] ToByteArray(this Image image, ImageFormat format)
    {
        using(MemoryStream ms = new MemoryStream())
        {
            image.Save(ms, format);
            return ms.ToArray();
        }
    }
}

আপনি কেবল এটির মতো ব্যবহার করতে পারেন:

var image = new Bitmap(10, 10);
// Draw your image
byte[] arr = image.ToByteArray(ImageFormat.Bmp);

আমি চিত্রাঙ্কনকারীর প্রসঙ্গে prestomanifto এর উত্তরের সাথে আংশিকভাবে একমত নই। ইমেজকনভার্টার ব্যবহার করবেন না। এটিতে প্রযুক্তিগতভাবে কোনও ভুল নেই, তবে কেবলমাত্র এটি সত্য যে এটি বক্স / আনবক্সিং অবজেক্ট থেকে ব্যবহার করে তা আমাকে। নেট ফ্রেমওয়ার্কের পুরানো অন্ধকার স্থানগুলির কোড এবং এটি চিত্র প্রক্রিয়াকরণের সাথে ব্যবহার করার জন্য আদর্শ নয় (এটি বাইটে রূপান্তরিত করার জন্য ওভারকিল) [] কমপক্ষে), বিশেষত যখন আপনি নিম্নলিখিতগুলি বিবেচনা করেন।

ImageConverter। নেট ফ্রেমওয়ার্ক দ্বারা ব্যবহৃত কোডটি আমি একবার দেখেছিলাম এবং অভ্যন্তরীণভাবে এটি আমার উপরে সরবরাহ করা কোডের মতো প্রায় একই রকম কোড ব্যবহার করে। এটি একটি নতুন তৈরি করে MemoryStream, Bitmapআপনি যখন সরবরাহ করেছিলেন তখন এটি যে আকারে ছিল সেটিকে সংরক্ষণ করে এবং অ্যারেটি ফিরিয়ে দেয়। ImageConverterব্যবহার করে ক্লাস তৈরির অতিরিক্ত ওভারহেড ছেড়ে যানMemoryStream


বাহ। ওইটাই করবো! আমি এটি গ্রহণ করেছি আপনি মেমোরিস্ট্রিমটি নিষ্পত্তি করতে চান, যদিও - আপডেটের যত্ন নিচ্ছেন?
জেরেমি ম্যাকগি

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

একটি এক্সটেনশন পদ্ধতির দুর্দান্ত ব্যবহার, আমি এটি পছন্দ করি!
ডুড পাস্কেলু

3
ইমেজ কনভার্টারের সন্ধান এবং আপনার গবেষণার ফলাফলের প্রতিবেদন করার জন্য +1। তবে আমি মনে করি না আপনি যা আবিষ্কার করেছেন তা "ইমেজ কনভার্টর ব্যবহার করবেন না" এই উক্তিটির পরোয়ানা দেয়। এটি অবশ্যই বাইট অ্যারে থেকে শুরু করে চিত্রের অন্য দিকে যেতে দরকারী পরিষেবাদি সরবরাহ করে উদাহরণস্বরূপ চিত্রের রেজোলিউশন (ডিপিআই) সেট করা। এবং "একটি ইমেজ কনভার্টারের শ্রেণি তৈরির অতিরিক্ত ওভারহেড" সম্ভবত অবহেলিত এবং আপনি এটি কতবার ব্যবহার না করেই কেবল একবার করা দরকার।
রেনিপেট

1
আমি ইমেজকনভার্টারটিকেও সহায়ক বলে মনে করেছি যাতে এটি চিত্রের ধরণটি স্বয়ংক্রিয়ভাবে নির্ধারণ করতে পারে - উদাহরণস্বরূপ যদি আপনার কাছে চিত্রটির বাইট অ্যারে থাকে তবে ফর্ম্যাটটি না জানেন - আপনি হেডারগুলি পড়তে এবং সেখান থেকে ইঙ্গিত পেতে চেষ্টা করতে পারেন, তবে, ভাল, ... (চিত্র img = (চিত্র) myImgConverter.ConvertFrom (বাইটআইমেজ)) এবং তারপরে img.Pixel Format ইত্যাদি পরীক্ষা করা সহজ ... - অবশ্যই আপনি কী করতে চান তার উপর নির্ভর করে
হ্যালো_ইর্থ

45

আপনি কেবল মার্শালও করতে পারেন the বিটম্যাপের ডেটা অনুলিপি করুন। কোনও মধ্যস্থতাকারী স্মৃতিপ্রবাহ ইত্যাদি নেই এবং একটি দ্রুত মেমরির অনুলিপি। এটি 24-বিট এবং 32-বিট বিটম্যাপ উভয় ক্ষেত্রেই কাজ করা উচিত।

public static byte[] BitmapToByteArray(Bitmap bitmap)
{

    BitmapData bmpdata = null;

    try
    {
        bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
        int numbytes = bmpdata.Stride * bitmap.Height;
        byte[] bytedata = new byte[numbytes];
        IntPtr ptr = bmpdata.Scan0;

        Marshal.Copy(ptr, bytedata, 0, numbytes);

        return bytedata;
    }
    finally
    {
        if (bmpdata != null)
            bitmap.UnlockBits(bmpdata);
    }

}


1
হাই, আমি এই পদ্ধতিটি ব্যবহার করেছি, তবে আমি এই বাইট অ্যারেটিকে আবার কোনও চিত্রে রূপান্তর করতে পারি না। বিটম্যাপ বিটম্যাপ 1 = নতুন বিটম্যাপ (নতুন মেমরিস্ট্রিম (অ্যারে)); এটি অবৈধ পরামিতিগুলির একটি ব্যতিক্রম ছুঁড়ে। কোন ভুল আছে?
হাওয়ার্ড

1
হাই, সম্পূর্ণ ক্লিন কোড পোস্ট করার জন্য মন্তব্য বিভাগটি আমার পক্ষে খুব ছোট। সহজ উপায় হ'ল অ্যারেটি পিন করা: GCHandle হ্যান্ডেল = GCHandle.Alloc (বাফেরারি, GCHandleType.Pinned); অ্যারের জন্য পয়েন্টারটি পান আইপিটিআর আইপিটিআর = মার্শাল Uউস্যাফএএডড্রঅফপিন্ডআররেইলেট (বাফেরারি, 0); তারপরে IntPtr ব্যবহার করে একটি নতুন বিটম্যাপ তৈরি করুন: বিটম্যাপ = নতুন বিটম্যাপ (প্রস্থ, উচ্চতা, (প্রস্থ * 4), পিক্সেলফর্ম্যাট.ফর্ম্যাট 32 বিপিএআরজিবি, আইপিটিআর); তবে আপনাকে আপনার বিটম্যাপ ফর্ম্যাটের জন্য উপযুক্ত বিটম্যাপ তৈরির প্যারামিটার ব্যবহার করতে হবে। পরিষ্কার করতে ভুলবেন না: iptr = IntPtr.Zero; handle.Free ();
ডিজেজি

3
বাগ কি? আমার সহ অনেক প্রোগ্রামার এই কোড স্টাইলটি ব্যবহার করছেন এবং এটি দুর্দান্ত কাজ করে।
ডিজেজি

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

3
এটি একটি বাগ নয়। msdn.microsoft.com/en-us/library/...
deegee

16

মেমোরিস্ট্রিমে চিত্রটি সংরক্ষণ করুন এবং তারপরে বাইট অ্যারেটি ধরুন।

http://msdn.microsoft.com/en-us/library/ms142148.aspx

  Byte[] data;

  using (var memoryStream = new MemoryStream())
  {
    image.Save(memoryStream, ImageFormat.Bmp);

    data = memoryStream.ToArray();
  }

চিত্রটিতে সংরক্ষণের পদ্ধতি নেই।
প্রেসকোট চারটিয়ার

@ প্রেসকোটচ্যারিয়ার উপরের উদাহরণটি ধরে নেওয়া হচ্ছে যে আপনি প্রাপ্ত একটি প্রকার থেকে কাজ করছেন System.Drawing.Image (দেখুন: ডকস.মাইক্রোসফটকম / ইয়েন / ডটনেট / এপি / )
ক্রিস

হ্যাঁ এবং আমি পেতে System.Drawing.Image does not exist। সুতরাং .. না, কাজ করে না :(
প্রেসকোট চারটিয়ার

আমি এখানে যা করার চেষ্টা করছি তা আপনি দেখতে পারেন: stackoverflow.com/questions/55084620/…
প্রেসকোট চারটিয়ার

10

এর MemoryStreamপরিবর্তে এর পরিবর্তে একটি ব্যবহার করুন FileStream:

MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();

আপনি সম্ভবত চান ToArray, না GetBuffer
vcsjones

গেটবফার স্বাক্ষরবিহীন বাইটের একটি অ্যারে ফেরত দেয় (বাইট অ্যারে)
জেফ রেড্ডি

4
এটিতে ফিলার ডেটা থাকতে পারে যা চিত্রের অংশ নয়। দস্তাবেজগুলি থেকে: Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method.সুতরাং এখন থেকে বাইট অ্যারে GetBufferচিত্রটি প্লাস অব্যবহৃত বাইটগুলি ফিরিয়ে দেবে, যার ফলস্বরূপ সম্ভবত কোনও দূষিত চিত্র দেখা যাবে।
vcsjones

1
জানা ভাল. ভিসি মন্তব্য করার জন্য ধন্যবাদ!
জেফ রেড্ডি

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

8

নিম্নলিখিত চেষ্টা করুন:

MemoryStream stream = new MemoryStream();
Bitmap bitmap = new Bitmap();
bitmap.Save(stream, ImageFormat.Jpeg);

byte[] byteArray = stream.GetBuffer();

আপনি ব্যবহার করছেন তা নিশ্চিত করুন:

System.Drawing & using System.Drawing.Imaging;

1
এই পদ্ধতির চিত্রটিকে ডিফল্ট সংক্ষেপণ সেটিংস সহ জেপিগ হিসাবে সংরক্ষণ করে, যা আপনার চিত্রটি দৃশ্যমানভাবে হ্রাস করতে পারে এমন সংকোচনের আর্টেফেক্সগুলি প্রবর্তন করবে।
রিচার্ড ইভ

আবার, বিটম্যাপে কোনও সংরক্ষণের পদ্ধতি নেই।
প্রেসকোট চারটিয়ার

7

আমি বিশ্বাস করি আপনি কেবল এটি করতে পারেন:

ImageConverter converter = new ImageConverter();
var bytes = (byte[])converter.ConvertTo(img, typeof(byte[]));

6
MemoryStream ms = new MemoryStream();
yourBitmap.Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();


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