কীভাবে কোনও অঙ্কনযোগ্যকে বিটম্যাপে রূপান্তর করতে?


947

আমি Drawableডিভাইসের ওয়ালপেপার হিসাবে একটি নির্দিষ্ট সেট করতে চাই , তবে সমস্ত ওয়ালপেপার ফাংশন Bitmapকেবলমাত্র তা গ্রহণ করে । আমি ব্যবহার করতে পারছি না WallpaperManagerকারণ আমি ২.১ পূর্ববর্তী।

এছাড়াও, আমার অঙ্কনযোগ্যগুলি ওয়েব থেকে ডাউনলোড করা হয় এবং এতে থাকে না R.drawable



1
: দয়া করে সঠিক উত্তর, এই চয়ন stackoverflow.com/a/3035869/4548520
user25

উত্তর:


1289

এই কোডটির টুকরো সহায়তা করে।

Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
                                           R.drawable.icon_resource);

এখানে একটি সংস্করণ যেখানে চিত্রটি ডাউনলোড হয়।

String name = c.getString(str_url);
URL url_value = new URL(name);
ImageView profile = (ImageView)v.findViewById(R.id.vdo_icon);
if (profile != null) {
    Bitmap mIcon1 =
        BitmapFactory.decodeStream(url_value.openConnection().getInputStream());
    profile.setImageBitmap(mIcon1);
}

1
আমি মনে করি আপনার ইউআরএল মান আছে। তাহলে আমার সম্পাদিত উত্তরের সাহায্য করা উচিত।
প্রবীণ

str_url কোথা থেকে আসে? স্ট্রিং সম্পর্কিত কোনও অঙ্কনযোগ্য ফাংশন আমি পাইনি ... আপনার সহায়তার জন্য ধন্যবাদ।
রব

12
আমি মনে করি যে আমি কিছু পেয়েছি: যদি "অঙ্কন" হ'ল অঙ্কনযোগ্য আমি তখনই বিটম্যাপে রূপান্তর করতে চাই: বিটম্যাপ বিটম্যাপ = ((বিটম্যাপড্রেবল) অঙ্কন) .getBitmap (); কৌতুক করে!
রব

1
@ রব: যদি আপনার ড্রয়যোগ্য কেবল বিটম্যাপড্রেইবল হয়। (যার অর্থ আপনার অঙ্কনযোগ্য কেবল বিটম্যাপের চারপাশে একটি র‌্যাপার, আসলে)
njzk2

2
দ্রষ্টব্য: এটি JPG এর সাথে বিশাল java.lang.OutOfMemoryError এর কারণ ঘটেছে
কেউ কোথাও

743
public static Bitmap drawableToBitmap (Drawable drawable) {
    Bitmap bitmap = null;

    if (drawable instanceof BitmapDrawable) {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
        if(bitmapDrawable.getBitmap() != null) {
            return bitmapDrawable.getBitmap();
        }
    }

    if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
        bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
    } else {
        bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    }

    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);
    return bitmap;
}

41
এটি একমাত্র উত্তরের মতো দেখায় যা কোনও ধরণের আঁকতে সক্ষম হয়ে কাজ করে এবং এমন একটি অঙ্কনযোগ্যর জন্য দ্রুত সমাধান রয়েছে যা ইতিমধ্যে বিটম্যাপড্রেবল। +1
ম্যাট ওল্ফ

1
কেবল একটি সংশোধনী: বিটম্যাপড্র্যাবেবল.জেট বিটম্যাপ () সম্পর্কে ডকস বলেছেন যে এটি বাতিল হয়ে যেতে পারে। আমি বলছি এটি ইতিমধ্যে পুনর্ব্যবহারযোগ্য ফিরে আসতে পারে।
কেলোগগুলি

16
সতর্কতা অবলম্বন করুন : getIntrinsicWidth()এবং getIntrinsicHieght()অঙ্কনযোগ্য একটি শক্ত রঙ হলে -1 ফিরে আসবে।
এসডি

5
সুতরাং ... কালারড্র্যায়েবলের জন্য অন্য একটি চেক, এবং আমাদের একটি বিজয়ী রয়েছে। গুরুতরভাবে, কেউ এটিকে গ্রহণযোগ্য উত্তর দেয় make
কায়ে

2
পতাকাঙ্কিত উত্তরের বিপরীতে, এই প্রশ্নের উত্তর দেয়।
njzk2

214

এটি একটি বিটম্যাপড্রেইবলকে বিটম্যাপে রূপান্তর করে।

Drawable d = ImagesArrayList.get(0);  
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();

9
এটা কি সত্যিই সেরা উপায়? অবশ্যই অঙ্কনযোগ্য অন্য ধরণের হতে পারে এবং এটি রানটাইম এক্সেকশনটি নিক্ষেপ করবে? উদাহরণস্বরূপ এটি নাইনপ্যাচড্রেবল হতে পারে ...?
ডরি

4
@ ডরি আপনি কোডটি শর্তযুক্ত বিবৃতিতে মোড়াতে পারতেন এটি পরীক্ষা করার BitmapDrawableআগে এটি সত্যিই একটি কিনা তা পরীক্ষা করতে: if (d instanceof BitmapDrawable) { Bitmap bitmap = ((BitmapDrawable)d).getBitmap(); }
টনি চ্যান

367
Up৪ টি উর্ধ্বে বিশ্বাস করা যায় না? কোডটি স্পষ্টতই কেবল তখনই কাজ করে যদি dইতিমধ্যে এটি একটি হয় BitmapDrawable, তবে এটি বিটম্যাপ হিসাবে পুনরুদ্ধার করা তুচ্ছ ... ClassCastExceptionঅন্য সমস্ত ক্ষেত্রে ক্র্যাশ হয়ে যাবে ।
ম্যাথিয়াস

3
@ মাথিয়াস তা উল্লেখ করবেন না .. প্রশ্ন নিজেই, একই লেখকের 100 টি ভোট রয়েছে: /
কুইনেস্টর

2
এটি একটি তুচ্ছ মামলায় তাই বিশেষীকরণযোগ্য।
njzk2

141

একটি Drawableএকটিতে আঁকতে পারে Canvasএবং একটি Canvasদ্বারা একটি সমর্থন করা যেতে পারে Bitmap:

( BitmapDrawableএর জন্য দ্রুত রূপান্তর পরিচালনা করতে এবং Bitmapতৈরির একটি বৈধ আকার রয়েছে তা নিশ্চিত করার জন্য আপডেট হয়েছে )

public static Bitmap drawableToBitmap (Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable)drawable).getBitmap();
    }

    int width = drawable.getIntrinsicWidth();
    width = width > 0 ? width : 1;
    int height = drawable.getIntrinsicHeight();
    height = height > 0 ? height : 1;

    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap); 
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}

অঙ্কনযোগ্য পরম নাল হলে কী হবে?
hrules6872

1
এই পদ্ধতিটি ভেক্টরড্রেবলকে সমর্থন করে না
মাহমুদ


ধরে নিচ্ছি যে আপনি একটি খালি খালি ড্রয়যোগ্য পাচ্ছেন, কেন প্রস্থ এবং উচ্চতা 0 নয় এটি যাচাই করা দরকার? এছাড়াও, আপনার সেটবাউন্ডগুলি () যদি একই আকারের হয় তবে তাদের ব্যবহারের প্রয়োজন কেন?
Yoav Feuerstein

ভাল সমাধান! অ্যান্ড্রয়েড 8.0 / এসডিকে 26 অ্যাপ্লিকেশনআইন.ফোড় আইকন (প্যাকেজ ম্যানেজার পিএম) একটি অ্যাডাপিটিভ আইকন ড্র্যাবেবল ফিরিয়ে দেয় your আপনার কোডটি আমাকে অ্যাডাপটিভ
আইকনড্রেইবলকে

43

পদ্ধতি 1 : হয় আপনি সরাসরি বিটম্যাপে রূপান্তর করতে পারেন

Bitmap myLogo = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_drawable);

পদ্ধতি 2 : আপনি এমনকি উত্সটিকে অঙ্কনযোগ্য রূপান্তর করতে পারেন এবং সেখান থেকে আপনি বিটম্যাপটি পেতে পারেন

Bitmap myLogo = ((BitmapDrawable)getResources().getDrawable(R.drawable.logo)).getBitmap();

জন্য এপিআই> 22 getDrawable পদ্ধতি সরানো ResourcesCompatতাই যে আপনি ভালো কিছু করতে বর্গ

Bitmap myLogo = ((BitmapDrawable) ResourcesCompat.getDrawable(context.getResources(), R.drawable.logo, null)).getBitmap();

রিসোর্সস কমপ্যাট কেবল তখনই কাজ করে যদি অঙ্কনযোগ্য একটি বিটম্যাপড্রেইবল হয়, আপনি যদি ভেক্টরড্রাব্যাবল ব্যবহার করে থাকেন তবে আপনার একটি সিসিই লাগবে।
ব্রিল পাপ্পিন

এগুলির কোনওটিই ভেক্টরড্র্যায়েবল সংস্থান নিয়ে কাজ করে না । নিম্নলিখিত ত্রুটির ঘটে -android.graphics.drawable.VectorDrawable cannot be cast to android.graphics.drawable.BitmapDrawable
আদম Hurwitz

এই সমাধানটি কোটলিনের সাথে ভালভাবে কাজ করে।
অ্যাডাম হুরউইটজ


15

সুতরাং অন্যান্য উত্তরগুলি দেখার (এবং ব্যবহার করে) দেখার পরে মনে হচ্ছে এগুলি সমস্তই পরিচালনা করছে ColorDrawableএবং PaintDrawableখারাপভাবে। (বিশেষত ললিপপে) দেখে মনে হয়েছিল যে Shaderএটিগুলি টুইট করা হয়েছে যাতে রঙের শক্ত ব্লকগুলি সঠিকভাবে পরিচালনা করা যায় না।

আমি এখন নিম্নলিখিত কোড ব্যবহার করছি:

public static Bitmap drawableToBitmap(Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable) drawable).getBitmap();
    }

    // We ask for the bounds if they have been set as they would be most
    // correct, then we check we are  > 0
    final int width = !drawable.getBounds().isEmpty() ?
            drawable.getBounds().width() : drawable.getIntrinsicWidth();

    final int height = !drawable.getBounds().isEmpty() ?
            drawable.getBounds().height() : drawable.getIntrinsicHeight();

    // Now we check we are > 0
    final Bitmap bitmap = Bitmap.createBitmap(width <= 0 ? 1 : width, height <= 0 ? 1 : height,
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}

অন্যদের থেকে ভিন্ন, যদি আপনি এটিটিকে বিটম্যাপে রূপান্তরিত করতে বলার আগে কল setBoundsকরেন Drawable, এটি বিটম্যাপটি সঠিক আকারে আঁকবে!


সেটবাউন্ডসগুলি অঙ্কনযোগ্যগুলির পূর্বের সীমানা নষ্ট করবে না? এটি সংরক্ষণ এবং পরে এটি পুনরুদ্ধার করা ভাল না?
অ্যান্ড্রয়েড বিকাশকারী

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

@ ক্রিস। জেনকিনস এর সীমা না থাকলে কী হবে এবং এখন এটি নতুন পাওয়া যাবে? আমি আরও একটি প্রশ্ন জিজ্ঞাসা করতে চাই: বিটম্যাপ আকার (এমনকি বিটম্যাপড্রেবলের জন্যও) সেট করার সর্বোত্তম উপায়টি কী ফিরে আসে?
অ্যান্ড্রয়েড বিকাশকারী

আমি আপনাকে সাবধানে কোডটি পড়ার পরামর্শ দিচ্ছি। যদি Drawableসীমানা সেট না থাকে তবে এটি ব্যবহার করে IntrinsicWidth/Height। যদি সেগুলি উভয়ই থাকে <= 0 আমরা ক্যানভাসকে 1px এ সেট করি। আপনি সঠিক যদি এর Drawableসীমানা না থাকে তবে এটি কিছু পাস করা হবে (1x1 বেশিরভাগ ক্ষেত্রে) তবে এটি এমন বিষয়গুলির জন্য প্রয়োজনীয় ColorDrawableযাগুলির অভ্যন্তরীণ আকার নেই। আমরা যদি এটি না করে, এটি একটি নিক্ষেপ করবে Exception, আপনি 0x0 একটি ক্যানভাসে আঁকতে পারবেন না।
ক্রিস। জেনকিনস

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

13

সম্ভবত এটি কাউকে সহায়তা করবে ...

পিকচারড্রেয়েবল থেকে বিটম্যাপে, ব্যবহার করুন:

private Bitmap pictureDrawableToBitmap(PictureDrawable pictureDrawable){ 
    Bitmap bmp = Bitmap.createBitmap(pictureDrawable.getIntrinsicWidth(), pictureDrawable.getIntrinsicHeight(), Config.ARGB_8888); 
    Canvas canvas = new Canvas(bmp); 
    canvas.drawPicture(pictureDrawable.getPicture()); 
    return bmp; 
}

... যেমন প্রয়োগ করা হয়েছে:

Bitmap bmp = pictureDrawableToBitmap((PictureDrawable) drawable);

রব এর উত্তর সঙ্গে হিসাবে, আপনি একটি নির্দিষ্ট ধরনের প্রয়োজন করছি Drawable, এই ক্ষেত্রে একটি PictureDrawable
কাবুকো

4
"হতে পারে এটি কাউকে সহায়তা করবে ..."
মাউরো

11

এখানে আরও ভাল রেজোলিউশন

public static Bitmap drawableToBitmap (Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable)drawable).getBitmap();
    }

    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap); 
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}

public static InputStream bitmapToInputStream(Bitmap bitmap) {
    int size = bitmap.getHeight() * bitmap.getRowBytes();
    ByteBuffer buffer = ByteBuffer.allocate(size);
    bitmap.copyPixelsToBuffer(buffer);
    return new ByteArrayInputStream(buffer.array());
}

ইনপুটস্ট্রিম হিসাবে অঙ্কনযোগ্য বিটগুলি কীভাবে পড়তে হবে তা থেকে কোড


11

1) বিটম্যাপে অঙ্কনযোগ্য:

Bitmap mIcon = BitmapFactory.decodeResource(context.getResources(),R.drawable.icon);
// mImageView.setImageBitmap(mIcon);

2) অঙ্কনযোগ্য বিটম্যাপ:

Drawable mDrawable = new BitmapDrawable(getResources(), bitmap);
// mImageView.setDrawable(mDrawable);

10

@ ক্রিস। জেনকিন্সের দেওয়া উত্তরের উত্তম কোটলিন সংস্করণটি এখানে রয়েছে: https://stackoverflow.com/a/27543712/1016462

fun Drawable.toBitmap(): Bitmap {
  if (this is BitmapDrawable) {
    return bitmap
  }

  val width = if (bounds.isEmpty) intrinsicWidth else bounds.width()
  val height = if (bounds.isEmpty) intrinsicHeight else bounds.height()

  return Bitmap.createBitmap(width.nonZero(), height.nonZero(), Bitmap.Config.ARGB_8888).also {
    val canvas = Canvas(it)
    setBounds(0, 0, canvas.width, canvas.height)
    draw(canvas)
  }
}

private fun Int.nonZero() = if (this <= 0) 1 else this

8

অ্যান্ড্রয়েড একটি অ সোজা ফোউআর্ড সমাধান প্রদান করে: BitmapDrawable। বিটম্যাপটি পেতে, আমাদের এটিকে সংস্থান আইডি সরবরাহ R.drawable.flower_picকরতে হবে BitmapDrawableএবং তারপরে এটিতে কাস্ট করতে হবে Bitmap

Bitmap bm = ((BitmapDrawable) getResources().getDrawable(R.drawable.flower_pic)).getBitmap();

8

অ্যান্ড্রয়েড-কেটিএক্সের Drawable.toBitmapপদ্ধতি রয়েছে: https://android.github.io/android-ktx/core-ktx/androidx.graphics.drawable/android.ographicics.drawable.-drawable/to-bitmap.html

কোটলিন থেকে

val bitmap = myDrawable.toBitmap()

VectorDrawableকোটলিনে এটির জন্য সবচেয়ে সহজ সমাধান ! আরও বিস্তারিতভাবে এখানে এই এসও পোস্টে ভাগ করা ।
অ্যাডাম হুরউইটজ

5

এই কোডটি ব্যবহার করুন.ইটি আপনার লক্ষ্য অর্জনে আপনাকে সহায়তা করবে।

 Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.profileimage);
    if (bmp!=null) {
        Bitmap bitmap_round=getRoundedShape(bmp);
        if (bitmap_round!=null) {
            profileimage.setImageBitmap(bitmap_round);
        }
    }

  public Bitmap getRoundedShape(Bitmap scaleBitmapImage) {
    int targetWidth = 100;
    int targetHeight = 100;
    Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, 
            targetHeight,Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(targetBitmap);
    Path path = new Path();
    path.addCircle(((float) targetWidth - 1) / 2,
            ((float) targetHeight - 1) / 2,
            (Math.min(((float) targetWidth), 
                    ((float) targetHeight)) / 2),
                    Path.Direction.CCW);

    canvas.clipPath(path);
    Bitmap sourceBitmap = scaleBitmapImage;
    canvas.drawBitmap(sourceBitmap, 
            new Rect(0, 0, sourceBitmap.getWidth(),
                    sourceBitmap.getHeight()), 
                    new Rect(0, 0, targetWidth, targetHeight), new Paint(Paint.FILTER_BITMAP_FLAG));
    return targetBitmap;
}

3

BitmapFactory.decodeResource()বিটম্যাপটি স্বয়ংক্রিয়ভাবে স্কেল করে, তাই আপনার বিটম্যাপটি अस्पष्ट হয়ে উঠতে পারে। স্কেলিং রোধ করতে, এটি করুন:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap source = BitmapFactory.decodeResource(context.getResources(),
                                             R.drawable.resource_name, options);

অথবা

InputStream is = context.getResources().openRawResource(R.drawable.resource_name)
bitmap = BitmapFactory.decodeStream(is);

2

আপনি যদি কোটলিন ব্যবহার করছেন তবে নীচের কোডটি ব্যবহার করুন। এটা কাজ করবে

// চিত্রের পাথ ব্যবহার করার জন্য

val image = Drawable.createFromPath(path)
val bitmap = (image as BitmapDrawable).bitmap


1
 // get image path from gallery
protected void onActivityResult(int requestCode, int resultcode, Intent intent) {
    super.onActivityResult(requestCode, resultcode, intent);

    if (requestCode == 1) {
        if (intent != null && resultcode == RESULT_OK) {             
            Uri selectedImage = intent.getData();

            String[] filePathColumn = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            filePath = cursor.getString(columnIndex);

            //display image using BitmapFactory

            cursor.close(); bmp = BitmapFactory.decodeFile(filepath); 
            iv.setBackgroundResource(0);
            iv.setImageBitmap(bmp);
        }
    }
}

আমি মনে করি আপনি প্রশ্নটি ভুল পড়েছেন। প্রশ্নটি জিজ্ঞাসা করে: কীভাবে সিস্টেমের গ্যালারী নয় একটি
অঙ্কনীয়

1

ইমেজ ওয়ার্কার লাইব্রেরি বিটম্যাপকে অঙ্কনযোগ্য বা বেস 64 এবং বিপরীতে রূপান্তর করতে পারে।

val bitmap: Bitmap? = ImageWorker.convert().drawableToBitmap(sourceDrawable)

বাস্তবায়ন

প্রকল্প স্তরের গ্রেডলে

allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

অ্যাপ্লিকেশন স্তরের গ্রেডলে

dependencies {
            implementation 'com.github.1AboveAll:ImageWorker:0.51'
    }

আপনি বাহ্যিক থেকে বিটম্যাপস / অঙ্কনযোগ্য / বেস 64 চিত্রগুলি সঞ্চয় এবং পুনরুদ্ধার করতে পারেন।

এখানে চেক করুন। https://github.com/1AboveAll/ImageWorker/edit/master/README.md

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