বাইট অ্যারেতে চিত্র রূপান্তর করার দ্রুততম উপায়


106

আমি রিমোট ডেস্কটপ ভাগ করে নেওয়ার অ্যাপ্লিকেশন তৈরি করছি যাতে আমি ডেস্কটপের একটি চিত্র ক্যাপচার করি এবং এটি সংকুচিত করে এটি রিসিভারে প্রেরণ করি। চিত্রটি সংকুচিত করতে আমার এটিকে বাইটে রূপান্তর করতে হবে []।

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

public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
    MemoryStream ms = new MemoryStream();
    imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
    return  ms.ToArray();
}

public Image byteArrayToImage(byte[] byteArrayIn)
{
     MemoryStream ms = new MemoryStream(byteArrayIn);
     Image returnImage = Image.FromStream(ms);
     return returnImage;
}

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

তাহলে এই লক্ষ্য অর্জনের জন্য অন্য কোন পদ্ধতি আছে কি?


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

3
@ abc123: আপনার কোনওটি নিষ্পত্তি করার দরকার নেই MemoryStream; এটি সম্পূর্ণরূপে পরিচালিত সংস্থান, যদি না আপনি এটিকে রিমোটিংয়ে ব্যবহার করছেন। এই উভয় ক্ষেত্রেই সম্পদ নিষ্পত্তি করা অনুচিত হবে।
জন স্কিটি

1
@ জোনস্কিট আকর্ষণীয়, আপনি কি এর উপর একটি মাপদণ্ড করেছেন? .NET বস্তুটি যে গতিতে প্রকাশ করে? আমি জানি যে ডেটা টেবিলের জন্যও একই অনুরূপ যুক্তি রয়েছে এবং এখনও কোনও নিষ্পত্তি ব্যবহৃত হওয়ার সময় গার্বেল সংগ্রহকারী বরাদ্দকৃত মেমরি সংগ্রহ করার গতিতে একটি লক্ষণীয় পার্থক্য রয়েছে।
abc123

@ abc123: আমি সত্যিই সেখানে প্রত্যাশা করব না - স্ট্রিমটি নিষ্পত্তি করা অ্যারের সাথে কিছুই করে না, এবং মেমোরিস্ট্রিমের একটি ফাইনালাইজার নেই (ডেটা টেবিলের বিপরীতে, যা মার্শালবাইভ্যালু কম্পোনেন্টের অংশ হিসাবে উত্তরাধিকার সূত্রে প্রাপ্ত)।
জন স্কিটি

2
পূর্ণ উত্স কোড সহ কোনও চূড়ান্ত সমাধান?
কিকিনেট

উত্তর:


39

তাহলে এই লক্ষ্য অর্জনের জন্য অন্য কোন পদ্ধতি আছে কি?

নং অর্ডার বাইট অ্যারের আপনাকে একটি চিত্র রুপান্তরিত করার আছে একটি চিত্র বিন্যাস নির্দিষ্ট করতে - আপনি যখন আপনি একটি বাইট অ্যারের পাঠ্য রূপান্তর এনকোডিং নির্দিষ্ট করতে হবে ঠিক যেমন।

আপনি যদি সংকোচনের আর্টেফ্যাক্টগুলি সম্পর্কে উদ্বিগ্ন হন তবে একটি ক্ষতিবিহীন বিন্যাস চয়ন করুন। আপনি যদি সিপিইউ সংস্থান সম্পর্কে উদ্বিগ্ন হন তবে এমন একটি বিন্যাস চয়ন করুন যা সংকোচনের বিরক্ত করে না - উদাহরণস্বরূপ কেবল কাঁচা এআরজিবি পিক্সেল। তবে অবশ্যই এটি একটি বৃহত বাইট অ্যারের দিকে নিয়ে যাবে।

মনে রাখবেন যে আপনি যদি এমন একটি বিন্যাস চয়ন করেন যা সংকোচনের সাথে অন্তর্ভুক্ত থাকে তবে বাইট অ্যারের পরে সংকোচনের কোনও মানে নেই - এটির কোনও লাভজনক প্রভাব নেই এটি প্রায় নিশ্চিত।


12
'লসলেস ফর্ম্যাটটি বেছে নেওয়ার' চেয়ে আপনি বেছে নিতে পারেন imageIn.RawFormatযা আর পুনরায় এনকোডিং ছাড়াই কাঁচা চিত্র বাইট সংরক্ষণের চেষ্টা করে।
ক্রিস এফ ক্যারল

52

ইমেজ প্যারামিটারের একটি রফফর্ম্যাট সম্পত্তি রয়েছে যা চিত্রের ফাইল ফর্ম্যাটটি দেয়। আপনি নিম্নলিখিত চেষ্টা করতে পারেন:

// extension method
public static byte[] imageToByteArray(this System.Drawing.Image image)
{
    using(var ms = new MemoryStream())
    {
        image.Save(ms, image.RawFormat);
        return ms.ToArray();
    }
}


@ নিল।আলেন আমি এখানে নতুন আছি আপনি কি দয়া করে বলতে পারেন?
খলিল খালাফ

3
@ ফার্স্টস্টেপ কারণ নিজের পরে পরিষ্কার করুন :)
সিনায়েস্টিক

@ সিনিস্টেথিক আমি দেখছি এবং রুটিনটি হ'ল আমি যে ফাংশনটি সম্পাদন করতে চাই তার ব্যবহার () {using ব্যবহার করে রাখি?
খলিল খালাফ

2
পছন্দ করেছেন আরও সঠিকভাবে: আপনি যদি এমন কোনও বস্তু ব্যবহার করেন যা আইডিস্পোজেবল কার্যকর করেছে, তবে আপনি যখন এটি সম্পন্ন করেছেন তখন আপনি ডিসপোজ () এ কল করতে ভুলবেন না যাতে এটি যে কোনও সংস্থানগুলি সংযুক্ত করে তা পরিষ্কার করে দেয়। () {} স্টেটমেন্টটি ব্যবহার যখন কেবল যখন অবজেক্টের statement বিবরণের বাইরে চলে যায় তখন এটি আপনার জন্য কল করে। সুতরাং আপনি myObject.Dispose()বা using(myObject){}- উভয়ই একই জিনিস করতে পারেন , তবে ব্যবহারের বিবৃতিটি মূলত এমন একটি সুযোগ তৈরি করে যা আপনার পক্ষে পরিষ্কার হয়ে যাবে।
সিনায়েস্টিক

14

আমি নিশ্চিত না যে আপনি জন স্কিটির নির্দেশিত কারণে যে কোনও বিশাল লাভ করতে যাচ্ছেন কিনা I'm তবে আপনি টাইপ কনভার্ট.কনভার্টটো পদ্ধতিটি চেষ্টা করে দেখতে পারেন এবং এটি আপনার বর্তমান পদ্ধতিটি ব্যবহারের সাথে কীভাবে তুলনা করে তা দেখতে পারেন।

ImageConverter converter = new ImageConverter();
byte[] imgArray = (byte[])converter.ConvertTo(imageIn, typeof(byte[]));

'System.Brate [চিত্র] টাইপ করতে' System.Byte [] 'টাইপের অবজেক্ট কাস্ট করতে অক্ষম।
ব্যবহারকারী 123

14
public static byte[] ReadImageFile(string imageLocation)
    {
        byte[] imageData = null;
        FileInfo fileInfo = new FileInfo(imageLocation);
        long imageFileLength = fileInfo.Length;
        FileStream fs = new FileStream(imageLocation, FileMode.Open, FileAccess.Read);
        BinaryReader br = new BinaryReader(fs);
        imageData = br.ReadBytes((int)imageFileLength);
        return imageData;
    }

5
উপরের কোড নমুনা কেন সহায়তা করে তা ব্যাখ্যা করার জন্য আপনি কি স্ট্যাকওভারফ্লো ডট কম এ স্বাগতম add এটি অন্য এসও ব্যবহারকারীদের জন্য যারা এটি পুরোপুরি বুঝতে না পারে ... স্ট্যাকওভারফ্লো
ম্যাক

এটি ফাইলগুলির জন্য বাইটে, তবে ওপি চাইছিল একটি অঙ্কন বস্তু বাইটে রূপান্তরিত। অঙ্কন বস্তুগুলি ডাটাবেসে সংরক্ষণ করা যেতে পারে, অগত্যা ফাইল সিস্টেমটি বাইটের অ্যারে হিসাবে নয়, এবং তাই সামনে এবং পিছনে রূপান্তর করতে হবে ... তবে কোনও ফাইল স্ট্রিমের ফাইল হিসাবে বাইটে রূপান্তর করতে হবে না - যদি না সম্ভবত প্রাথমিক আপলোড।
vapcguy

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

5
public static class HelperExtensions
{
    //Convert Image to byte[] array:
    public static byte[] ToByteArray(this Image imageIn)
    {
        var ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        return ms.ToArray();
    }

    //Convert byte[] array to Image:
    public static Image ToImage(this byte[] byteArrayIn)
    {
        var ms = new MemoryStream(byteArrayIn);
        var returnImage = Image.FromStream(ms);
        return returnImage;
    }
}

2

আমি দ্রুততম উপায়টি জানতে পারি এটি হ'ল:

var myArray = (byte[]) new ImageConverter().ConvertTo(InputImg, typeof(byte[]));

আশা করি কাজে লাগবে


এটির সাথে সাবধানতা অবলম্বন করুন, বিশেষত যদি ডাব্লুপিএফ ব্যবহার করে যেখানে আপনার System.Windows.Controls.Imageজিনিস থাকবে। আপনি যদি এইগুলির মধ্যে একটিকে বাইটে রূপান্তর করতে চান এবং আপনি এটিকে এই লাইনে পাস করেন তবে এটি কার্যকর InputImgহবে না। এটি একটি System.Drawing.Imageবস্তুর প্রত্যাশা করে ।
vapcguy
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.