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


292
  Bitmap bmp   = intent.getExtras().get("data");
  int size     = bmp.getRowBytes() * bmp.getHeight();
  ByteBuffer b = ByteBuffer.allocate(size);

  bmp.copyPixelsToBuffer(b);

  byte[] bytes = new byte[size];

  try {
     b.get(bytes, 0, bytes.length);
  } catch (BufferUnderflowException e) {
     // always happens
  }
  // do something with byte[]

যখন আমি বাফারের দিকে তাকানোর পরে copyPixelsToBufferবাইটগুলিতে কল সমস্ত 0 হয় ... ক্যামেরা থেকে ফিরে আসা বিটম্যাপটি অপরিবর্তনীয় ... তবে এটি অনুলিপি করার পরে এটি বিবেচ্য নয়।

এই কোডটি দিয়ে কী ভুল হতে পারে?

উত্তর:


652

এরকম কিছু চেষ্টা করুন:

Bitmap bmp = intent.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
bmp.recycle();

9
চিত্রটি পিএনজি টাইপের না হলে এই সমস্যার কারণ হবে না?
pgsandstrom

7
কারণ বিটম্যাপটি পিক্সেল অ্যারের মতো যা ছিল তা নির্বিশেষে একটি ডিকোডেড চিত্র won't এটি পিএনজি হিসাবে সংকোচিত হবে, যা

5
@ টেড হপ্পের রিওয়াইন্ড অপশনটি আরও ভাল - এটির সংকোচন করা সিপিইউয়ের অপচয় নয় যদি না আপনার লক্ষ্য একটি এনকোডড চিত্র হয় ....
কওলিন ফায়ার

38
আমার অভিজ্ঞতায় অ্যান্ড্রয়েডের মতো লো-মেমরি সিস্টেমে বিটম্যাপ.রেইসিল () যুক্ত করার জন্য মনোযোগী হতে হবে; সংক্ষেপণের ঠিক পরে, এবং মেমরি ফাঁস ব্যতিক্রম এড়ানোর জন্য স্ট্রিমটি বন্ধ করুন।
পুত্র হুই ট্রান

10
এই পদ্ধতির বরাদ্দ সত্যই অপ্রয়োজনীয়। তোমার ByteArrayOutputStreamবরাদ্দ হবে যারা একটি byte[]আকার এর সমান byte[]আপনার ব্যাক Bitmap, তারপর ByteArrayOutputStream.toByteArray()আরেকটি আবার বরাদ্দ হবে byte[]একই আকারের।
zyamys

70

কমপ্রেস ফর্ম্যাটটি খুব ধীর ...

বাইটবফার ব্যবহার করে দেখুন।

By বিটম্যাপ থেকে বাইট ※※※

width = bitmap.getWidth();
height = bitmap.getHeight();

int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(byteBuffer);
byteArray = byteBuffer.array();

Bit বাইট টু বিটম্যাপ ※※※

Bitmap.Config configBmp = Bitmap.Config.valueOf(bitmap.getConfig().name());
Bitmap bitmap_tmp = Bitmap.createBitmap(width, height, configBmp);
ByteBuffer buffer = ByteBuffer.wrap(byteArray);
bitmap_tmp.copyPixelsFromBuffer(buffer);

5
যেহেতু এই প্রশ্নটিতে অ্যান্ড্রয়েড ট্যাগ রয়েছে, বাইটকে একটি বিটম্যাপে রূপান্তর করা ওয়ান-লাইনারের সাহায্যেও করা যেতে পারে: আপনার বাইট অ্যারেটি Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length) কোথায়bytes
অটোমেটন

সম্ভবত বড় / ছোট এন্ডিয়ান বিবেচনা করা উচিত?
নিওওয়াং

আপনি যদি স্থানীয় ডিবিতে বাইট অ্যারে সংরক্ষণ করতে চান (স্ক্লাইট, ঘর), আপনার উপরের উত্তর মত সংকোচ করা উচিত!
জে.ড্রেগন

তবে নোট করুন, সংক্ষেপণ ছাড়াই আকারের পার্থক্যটি নাটকীয়। তত্ত্বের জন্য আপনি উইকিপিডিয়া পড়তে পারেন, তবে উদাহরণস্বরূপ আমার ক্ষেত্রে সংকুচিত ফলাফল (প্রথম উত্তর অনুসারে) 20 এমবি, অন্যটি (এই উত্তর) 48 এমবি
কিরিল স্টারোস্টিন

19

এখানে .convertToByteArrayকোটলিনে বিটম্যাপ এক্সটেনশন লেখা হয়েছে।

/**
 * Convert bitmap to byte array using ByteBuffer.
 */
fun Bitmap.convertToByteArray(): ByteArray {
    //minimum number of bytes that can be used to store this bitmap's pixels
    val size = this.byteCount

    //allocate new instances which will hold bitmap
    val buffer = ByteBuffer.allocate(size)
    val bytes = ByteArray(size)

    //copy the bitmap's pixels into the specified buffer
    this.copyPixelsToBuffer(buffer)

    //rewinds buffer (buffer position is set to zero and the mark is discarded)
    buffer.rewind()

    //transfer bytes from buffer into the given destination array
    buffer.get(bytes)

    //return bitmap's pixels
    return bytes
}

18

আপনার কি সম্ভবত বাফারটি রিওয়াইন্ড করা দরকার?

এছাড়াও, যদি বিটম্যাপের স্ট্রাইড (বাইটগুলিতে) পিক্সেল * বাইট / পিক্সেলের সারি দৈর্ঘ্যের চেয়ে বেশি হয় তবে এটি ঘটতে পারে। আকারের পরিবর্তে বাইটের দৈর্ঘ্যকে b.remaining () করুন।


6
rewind()চাবিকাঠি আমি একই BufferUnderflowExceptionহচ্ছিলাম এবং এটি পূরণ করার পরে বাফারটিকে রিওয়াইন্ড করছিলাম resolved
tstuts

9

বাইট [] এবং বিপরীতে বিটম্যাপ এনকোড করতে নীচের ফাংশনগুলি ব্যবহার করুন

public static String encodeTobase64(Bitmap image) {
    Bitmap immagex = image;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    immagex.compress(Bitmap.CompressFormat.PNG, 90, baos);
    byte[] b = baos.toByteArray();
    String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);
    return imageEncoded;
}

public static Bitmap decodeBase64(String input) {
    byte[] decodedByte = Base64.decode(input, 0);
    return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}

6

আপনার বাইট অ্যারে খুব ছোট। প্রতিটি পিক্সেল 4 বাইট নেয়, কেবল 1 নয়, তাই আপনার আকারকে * 4 গুণান যাতে অ্যারে যথেষ্ট বড় হয়।


4
তার বাইট অ্যারে যথেষ্ট বড়। getRowBytes()অ্যাকাউন্টে পিক্সেল প্রতি 4 বাইট নেয়।
tstuts

3

টেড হপ সঠিক, এপিআই ডকুমেন্টেশন থেকে:

public void copyPixelsToBuffer (Buffer dst)

"... এই পদ্ধতিটি ফিরে আসার পরে, বাফারের বর্তমান অবস্থান আপডেট করা হয়েছে: বাফারে লিখিত উপাদানগুলির সংখ্যা দ্বারা অবস্থানটি বাড়ানো হয়।"

এবং

public ByteBuffer get (byte[] dst, int dstOffset, int byteCount)

" নির্দিষ্ট অফসেট থেকে শুরু করে বর্তমান অবস্থান থেকে নির্দিষ্ট বাইট অ্যারেতে বাইটগুলি পড়ে এবং পঠিত বাইটের সংখ্যা দ্বারা অবস্থান বৃদ্ধি করে।"


2

OutOfMemoryবড় ফাইলগুলির জন্য ত্রুটি এড়াতে , আমি বিটম্যাপটি কয়েকটি অংশে বিভক্ত করে এবং তার অংশগুলির বাইটগুলি মার্জ করে কাজটি সমাধান করব।

private byte[] getBitmapBytes(Bitmap bitmap)
{
    int chunkNumbers = 10;
    int bitmapSize = bitmap.getRowBytes() * bitmap.getHeight();
    byte[] imageBytes = new byte[bitmapSize];
    int rows, cols;
    int chunkHeight, chunkWidth;
    rows = cols = (int) Math.sqrt(chunkNumbers);
    chunkHeight = bitmap.getHeight() / rows;
    chunkWidth = bitmap.getWidth() / cols;

    int yCoord = 0;
    int bitmapsSizes = 0;

    for (int x = 0; x < rows; x++)
    {
        int xCoord = 0;
        for (int y = 0; y < cols; y++)
        {
            Bitmap bitmapChunk = Bitmap.createBitmap(bitmap, xCoord, yCoord, chunkWidth, chunkHeight);
            byte[] bitmapArray = getBytesFromBitmapChunk(bitmapChunk);
            System.arraycopy(bitmapArray, 0, imageBytes, bitmapsSizes, bitmapArray.length);
            bitmapsSizes = bitmapsSizes + bitmapArray.length;
            xCoord += chunkWidth;

            bitmapChunk.recycle();
            bitmapChunk = null;
        }
        yCoord += chunkHeight;
    }

    return imageBytes;
}


private byte[] getBytesFromBitmapChunk(Bitmap bitmap)
{
    int bitmapSize = bitmap.getRowBytes() * bitmap.getHeight();
    ByteBuffer byteBuffer = ByteBuffer.allocate(bitmapSize);
    bitmap.copyPixelsToBuffer(byteBuffer);
    byteBuffer.rewind();
    return byteBuffer.array();
}

0

স্ট্রিং-বিটম্যাপ বা বিটম্যাপ-স্ট্রিং রূপান্তর করতে এটি ব্যবহার করে দেখুন

/**
 * @param bitmap
 * @return converting bitmap and return a string
 */
public static String BitMapToString(Bitmap bitmap){
    ByteArrayOutputStream baos=new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
    byte [] b=baos.toByteArray();
    String temp=Base64.encodeToString(b, Base64.DEFAULT);
    return temp;
}

/**
 * @param encodedString
 * @return bitmap (from given string)
 */
public static Bitmap StringToBitMap(String encodedString){
    try{
        byte [] encodeByte=Base64.decode(encodedString,Base64.DEFAULT);
        Bitmap bitmap= BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
        return bitmap;
    }catch(Exception e){
        e.getMessage();
        return null;
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.