एक बिटमैप को बाइट सरणी में बदलें


233

C # का उपयोग करना, क्या विंडोज 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();
    }
}

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

स्रोत: http://www.vcskicks.com/image-to-byte.php


2
आप बिटमैप का उपयोग भी कर सकते हैं। किसी भी मध्यवर्ती
मेमोरीस्ट्रीम

4
कृपया ध्यान रखें कि ImageConverterविधि Png के रूप में छवि को बचाएगा, जिसके परिणामस्वरूप बड़ी फ़ाइलें हैं।
skolima

8
'का उपयोग कर' जब आप धारा को बंद करने की जरूरत नहीं है
LastTribunal

2
क्या कोई मुझे इस बारे में थोड़ी और जानकारी दे सकता है कि यह सरणी कैसे संरचित है? क्या यह x = 0 से शुरू होता है और हर y के माध्यम से चक्र और फिर x को बढ़ाता है? और फिर इसे इस तरह स्टोर करें: [0,0,1,1,1,1,0,0,1,1]?
रेमंड टिम्मरमैन

1
ImageConverter.net मानक आप उपयोग नहीं कर सकते हैं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);

मैं ImageConverter के संबंध में prestomanifto के जवाब से आंशिक रूप से असहमत हूं। ImageConverter का उपयोग न करें। इसके साथ तकनीकी रूप से कुछ भी गलत नहीं है, लेकिन बस यह तथ्य है कि यह बॉक्सिंग / ऑब्जेक्ट से बॉक्सिंग का उपयोग करता है, मुझे बताता है कि यह .NET फ्रेमवर्क के पुराने अंधेरे स्थानों से कोड है और छवि प्रसंस्करण के साथ उपयोग करने के लिए आदर्श नहीं है (यह बाइट में परिवर्तित करने के लिए ओवरकिल है। [] कम से कम), खासकर जब आप निम्नलिखित पर विचार करते हैं।

मैंने ImageConverter.Net फ्रेमवर्क द्वारा उपयोग किए गए कोड पर एक नज़र डाली, और आंतरिक रूप से यह ऊपर दिए गए कोड के समान कोड का उपयोग करता है। यह एक नया बनाता है MemoryStream, Bitmapजब आपने इसे प्रदान किया था, तो जो भी प्रारूप में था उसे सहेजता है और सरणी देता है। ImageConverterउपयोग करके कक्षा बनाने के अतिरिक्त ओवरहेड को छोड़ेंMemoryStream


लवली। यह सही रहेगा! मुझे लगता है कि आप MemoryStream को निपटाना चाहते हैं, हालांकि - अद्यतन करने के लिए देखभाल?
जेरेमी मैकगी

मैंने अपने उत्तर को कुछ चर्चा के साथ अद्यतन किया है कि क्यों नहीं ImageConverter का उपयोग किया जाए, जैसा कि आपके चयनित उत्तर से पता चलता है, साथ ही निपटान के अलावा भी।
क्रिस्टोफर Currens

एक विस्तार विधि का अच्छा उपयोग, मुझे यह पसंद है!
यार पास्कलौ जूल

3
ImageConverter में देखने और अपने शोध के परिणामों की रिपोर्ट करने के लिए +1। लेकिन मुझे नहीं लगता कि आपने जो वारंट खोजा है वह कथन "ImageConverter का उपयोग न करें।" यह निश्चित रूप से बाइट सरणी से छवि तक दूसरे रास्ते पर जाने वाली उपयोगी सेवाएं प्रदान करता है, उदाहरण के लिए छवि रिज़ॉल्यूशन (डीपीआई) सेट करना। और "ImageConverter वर्ग बनाने का अतिरिक्त ओवरहेड" संभवतः नगण्य है, और केवल एक बार चाहे आप इसे कितनी भी बार उपयोग करें।
रेनीपेट

1
मैंने पाया कि ImageConverter भी इसमें मददगार है, यह छवि के प्रकार को स्वचालित रूप से निर्धारित कर सकता है - उदाहरण के लिए यदि आपके पास छवि का एक बाइट है, लेकिन प्रारूप को नहीं जानते हैं - आप हेडर पढ़ने और वहां से संकेत प्राप्त करने की कोशिश कर सकते हैं, लेकिन, खैर, ... (छवि img = (छवि) myImgConverter.ConvertFrom (byteImage) का उपयोग करना और फिर img.PixelFormat आदि की जांच करना आसान है .. - बेशक आप क्या करना चाहते हैं इसके आधार पर
hello_earth

45

आप सिर्फ मार्शल कर सकते हैं। बिटमैप डेटा को कॉपी करें। कोई मध्यस्थ मेमोरीस्ट्रीम आदि और एक तेज़ मेमोरी कॉपी नहीं। यह 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); सरणी के लिए सूचक प्राप्त करें IntPtr iptr = Marshal.UnsafeAddrOfPinnedArrayElement (बफरएरे, 0); फिर IntPtr का उपयोग करके एक नया बिटमैप बनाएं: बिटमैप = नया बिटमैप (चौड़ाई, ऊंचाई, (चौड़ाई * 4), PixelFormat.Format32bppArgb, iptr); लेकिन आपको अपने बिटमैप प्रारूप के लिए उपयुक्त बिटमैप निर्माण मापदंडों का उपयोग करना होगा। साफ करना सुनिश्चित करें: iptr = IntPtr.Zero; handle.Free ();
डेग्यू

3
बग क्या है? स्वयं सहित कई प्रोग्रामर इस कोड शैली का उपयोग कर रहे हैं और यह ठीक काम करता है।
डेग

4
@ मिनी-मी - मैं यह देखने की सलाह देता हूं कि बिटमैप स्ट्रेट बनाम बिटमैप चौड़ाई क्या है। यह मेरे कोड में बग नहीं है, यह है कि विंडोज बिटमैप कैसे संभालती है। स्ट्राइड में प्रत्येक पंक्ति के अंत में (चौड़ाई) अतिरिक्त डेटा शामिल हो सकता है ताकि प्रत्येक पंक्ति का अंत हो और स्मृति संरेखण और प्रदर्शन के लिए 32-बिट सीमा पर शुरू हो सके।
दीजे

3
यह बग नहीं है। msdn.microsoft.com/en-us/library/…
deegee

16

एक MemoryStream में छवि सहेजें और फिर बाइट सरणी को पकड़ो।

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

  Byte[] data;

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

    data = memoryStream.ToArray();
  }

इमेज पर सेव मेथड नहीं है।
प्रेस्कॉट चार्टिएर

@PrescottChartier उपरोक्त उदाहरण मान रहा है कि आप एक प्रकार से प्राप्त कार्य कर रहे हैं System.Drawing.Image (देखें: docs.microsoft.com/en-us/dotnet/api/… )
क्रिस बैक्सटर

हाँ और मुझे मिलता है 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

GetBuffer अहस्ताक्षरित बाइट्स की एक सरणी (बाइट सरणी)
जेफ रेड्डी

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
जानकार अच्छा लगा। टिप्पणी vcs के लिए धन्यवाद!
जेफ रेड्डी

यह दृष्टिकोण छवि को डिफ़ॉल्ट संपीड़न सेटिंग्स के साथ एक जेपीईजी के रूप में बचाता है, जो संपीड़न कलाकृतियों को पेश करेगा जो आपकी छवि को स्पष्ट रूप से नीचा दिखा सकता है।
रिचर्ड इव

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();


-3

बस एक लाइन में बहुत सरल उपयोग:

byte[] imgdata = File.ReadAllBytes(@"C:\download.png");

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