ভেক্টর অঙ্কনযোগ্য থেকে বিটম্যাপ প্রাপ্ত


132

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

কোডের নমুনা এখানে:

if (BitmapFactory.decodeResource(arg0.getResources(), R.drawable.vector_menu_objectifs) == null)
        Log.d("ISNULL", "NULL");
    else
        Log.d("ISNULL", "NOT NULL");

এই নমুনায়, আমি যখন R.drawable.vector_menu_objectifs একটি "সাধারণ" চিত্র, উদাহরণস্বরূপ একটি পিএনজি দিয়ে প্রতিস্থাপন করি, ফলাফলটি শূন্য হয় না (আমি সঠিক বিটম্যাপটি পেয়েছি) আমি কি অনুপস্থিত কিছু আছে?


1
ছিল similiar ইস্যু, সমাধান নয় কিন্তু একটি কার্যসংক্রান্ত: stackoverflow.com/questions/33548447/...
চেয়ে

উত্তর:


231

এপিআইতে চেক করা হয়েছে: 17, 21, 23

public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
    Drawable drawable = ContextCompat.getDrawable(context, drawableId);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        drawable = (DrawableCompat.wrap(drawable)).mutate();
    }

    Bitmap 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;
}

হালনাগাদ:

প্রকল্প গ্রেড:

dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0-alpha5'
    }

মডিউল গ্রেড:

android {
    compileSdkVersion 23
    buildToolsVersion '23.0.3'
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 23
        vectorDrawables.useSupportLibrary = true
    }
    ...
}
...

ধন্যবাদ. পূর্ববর্তী উত্তরটি এসডিকে সংস্করণ দিয়ে কাজ করছে না 23 থেকে শুরু হচ্ছে
পাহা

2
এটি আমার পক্ষে দুর্দান্ত কাজ করে। কোনও সমস্যা ছাড়াই এপিআই 15 এ চলছে
ভেরা

4
AppCompatDrawableManager@RestrictTo(LIBRARY_GROUP)এটি অভ্যন্তরীণ হিসাবে চিহ্নিত হয়েছে এবং আপনার এটি ব্যবহার করা উচিত নয় (এটি এপিআই বিজ্ঞপ্তি ছাড়াই পরিবর্তন করতে পারে)। ContextCompatপরিবর্তে ব্যবহার করুন।
mradzinski

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.Bitmap.setHasAlpha(boolean)' on a null object referenceএই লাইনে কাজ করে নাBitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
ব্যবহারকারী 25

5
এই সমাধান নিয়ে আমার সমস্যা ছিল। আমার ব্যবহারের জন্য: কনটেক্সট কম্পিউটারের পরিবর্তে অ্যাপকম্প্যাটআরসোর্সগুলি এটি স্থির করে: ড্রয়যোগ্য অঙ্কনযোগ্য = অ্যাপকোম্প্যাটআরসোর্স.জেটড্রেবল (প্রসঙ্গ, অঙ্কনযোগ্য);
মাইক টি

64

আপনি নিম্নলিখিত পদ্ধতিটি ব্যবহার করতে পারেন:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static Bitmap getBitmap(VectorDrawable vectorDrawable) {
    Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
            vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    vectorDrawable.draw(canvas);
    return bitmap;
}

যা আমি মাঝে মাঝে একত্রিত করি:

private static Bitmap getBitmap(Context context, int drawableId) {
    Drawable drawable = ContextCompat.getDrawable(context, drawableId);
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable) drawable).getBitmap();
    } else if (drawable instanceof VectorDrawable) {
        return getBitmap((VectorDrawable) drawable);
    } else {
        throw new IllegalArgumentException("unsupported drawable type");
    }
}

2
আশা করি @ লিটলফ ফিরে এসে এটিকে উত্তর হিসাবে চিহ্নিত করে। একটি বিষয় লক্ষণীয় হ'ল উভয় পদ্ধতিই টার্গেটপি-র মোড়ক চায় - তবে অ্যান্ড্রয়েড স্টুডিও আপনাকে তা জানাবে।
রবার্তো টমস

1
আমি এখন এর এসভিজি ফাইল সমস্যাটি ভেবে এটি করার চেষ্টা করে প্রায় দুই দিন অতিবাহিত করেছি। ধন্যবাদ!
স্পার্কলি_ফ্রাগ

1
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.Bitmap.setHasAlpha(boolean)' on a null object referenceএই লাইনে কাজ করে নাBitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
ব্যবহারকারী 25

45

আপনি যদি কোটলিনের জন্য অ্যান্ড্রয়েড কেটিএক্স ব্যবহার করতে ইচ্ছুক হন তবে আপনি Drawable#toBitmap()অন্যান্য উত্তরের মতো একই প্রভাব অর্জন করতে এক্সটেনশন পদ্ধতিটি ব্যবহার করতে পারেন :

val bitmap = AppCompatResources.getDrawable(requireContext(), drawableId).toBitmap() 

অথবা

val bitmap = AppCompatResources.getDrawable(context, drawableId).toBitmap() 

এটি এবং অন্যান্য দরকারী এক্সটেনশন পদ্ধতি যুক্ত করতে আপনার মডিউল-স্তরে নিম্নলিখিতগুলি যুক্ত করতে হবে build.gradle

repositories {
    google()
}

dependencies {
    implementation "androidx.core:core-ktx:1.2.0"
}

আপনার প্রকল্পের নির্ভরতা যুক্ত করার জন্য সর্বশেষ নির্দেশাবলীর জন্য এখানে দেখুন ।

নোট করুন যে এটি যে কোনও সাবক্লাসের জন্য কাজ করবে Drawableএবং যদি এটি Drawableহয় তবে BitmapDrawableএটি অন্তর্নিহিত ব্যবহার করার জন্য শর্টকাট করবে Bitmap


কোটলিনের জন্য এটি এখানে সবচেয়ে সহজ সমাধান simple
অ্যাডাম হুরউইটজ

1
আমার জন্য এটি পুরোপুরি সূক্ষ্মভাবে কাজ করে VectorDrawable
উবুন্টুড্রয়েড

এটি সেরা বিকল্প .. ডিফল্ট অ্যান্ড্রয়েডক্স কার্যকারিতা সরবরাহ করে
রেশমা

27

পূর্ববর্তী উত্তরের উপর ভিত্তি করে এটি ভেক্টরড্রেবল এবং বিটম্যাপড্রেবল উভয়ের সাথে মিলে যাওয়ার জন্য এবং কমপক্ষে এপিআই 15 এর সাথে সামঞ্জস্যপূর্ণ হওয়ার মতো সরল করা যেতে পারে।

public static Bitmap getBitmapFromDrawable(Context context, @DrawableRes int drawableId) {
    Drawable drawable = AppCompatResources.getDrawable(context, drawableId);

    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable) drawable).getBitmap();
    } else if (drawable instanceof VectorDrawableCompat || drawable instanceof VectorDrawable) {
        Bitmap 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;
    } else {
        throw new IllegalArgumentException("unsupported drawable type");
    }
}

তারপরে আপনাকে আপনার গ্রেড ফাইলটি যুক্ত করতে হবে:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

প্রি-লোলিপপটিতে এটি ভেক্টরড্রেভ্যাবলকম্প্যাট ব্যবহার করবে এবং ললিপপে এটি ভেক্টরড্রাব্যাবল ব্যবহার করবে।

সম্পাদনা

@ ব্যবহারকারী3109468 এর মন্তব্যের পরে আমি শর্তটি সম্পাদনা করেছি


1
ভেক্টর ড্রয়যোগ্য উদাহরণস্বরূপ || ভেক্টর ড্রয়যোগ্যকম্প্যাট এর অঙ্কনযোগ্য উদাহরণগুলির পক্ষগুলি অদলবদল করা উচিত। ভেক্টরড্রেবলের অস্তিত্ব না থাকাকালীন কোনও শ্রেণীর ফলাফল পাওয়া যায় নি, যখন ভেক্টরড্রেবলযোগ্য কমপ্যাটটি প্রথমে পরীক্ষা করা উচিত কারণ এটি বিদ্যমান নেই।
ওয়ারিক

VertorDrawable টাইপ চেকিং হিসাবে বর্ণনা করা যেতে পারে(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && drawable instanceof VectorDrawable)
chmin

6

ক্যালস টু @ অ্যালেক্সায়

Kotlinএক্সটেনশানগুলি ব্যবহার করে এখানে সংস্করণ দেওয়া আছেContext

fun Context.getBitmapFromVectorDrawable(drawableId: Int): Bitmap? {
    var drawable = ContextCompat.getDrawable(this, drawableId) ?: return null

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        drawable = DrawableCompat.wrap(drawable).mutate()
    }

    val bitmap = Bitmap.createBitmap(
            drawable.intrinsicWidth,
            drawable.intrinsicHeight,
            Bitmap.Config.ARGB_8888) ?: return null
    val canvas = Canvas(bitmap)
    drawable.setBounds(0, 0, canvas.width, canvas.height)
    drawable.draw(canvas)

    return bitmap
}

ব্যবহারের উদাহরণ Activity:

val bitmap = this.getBitmapFromVectorDrawable(R.drawable.ic_done_white_24dp)

1

এপিআই 16-তে পরীক্ষিত - ভেক্টর ড্রয়যোগ্যদের সাথে জেলিবিয়ান

public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
    Drawable drawable = AppCompatResources.getDrawable(context, drawableId);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        drawable = (DrawableCompat.wrap(drawable)).mutate();
    }

    Bitmap 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;
}   

1

সঠিক দিক অনুপাত (উদাহরণস্বরূপ, বিজ্ঞপ্তি আইকন জন্য) সহ চিত্র রূপান্তর করতে নিম্নলিখিত কোডটি ব্যবহার করুন :

public static Bitmap getBitmapFromVector(Context context, int drawableId) {
    Drawable drawable = ContextCompat.getDrawable(context, drawableId);
    int width = drawable.getIntrinsicWidth();
    int height = drawable.getIntrinsicHeight();
    Bitmap bitmap;
    if (width < height) {    //make a square
        bitmap = Bitmap.createBitmap(height, height, Bitmap.Config.ARGB_8888);
    } else {
        bitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);
    }
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0,
            drawable.getIntrinsicWidth(),    //use dimensions of Drawable
            drawable.getIntrinsicHeight()
    );
    drawable.draw(canvas);
    return bitmap;
}

0

যদি আপনার vectorইমেজ intrinsicWidthএবং intrinsicHeightছোট এবং আপনি একটি বড় দৃশ্যে বিটম্যাপ প্রকাশ করার চেষ্টা করুন, তাহলে আপনি ফলাফলের দাগ হয় দেখতে হবে।

যে ক্ষেত্রে, আপনি আপনার বিটম্যাপ ভাল ইমেজ পেতে জন্য একটি নতুন প্রস্থ / উচ্চতা প্রদান করতে পারেন (অথবা আপনি XML- এর ভেক্টর আকার বৃদ্ধি করতে পারেন, কিন্তু প্রদান desireWidthএবং desireHeightআরও নমনীয় হতে পারে)।

private fun getBitmap(drawableId: Int, desireWidth: Int? = null, desireHeight: Int? = null): Bitmap? {
    val drawable = AppCompatResources.getDrawable(context, drawableId) ?: return null
    val bitmap = Bitmap.createBitmap(
        desireWidth ?: drawable.intrinsicWidth,
        desireHeight ?: drawable.intrinsicHeight,
        Bitmap.Config.ARGB_8888
    )
    val canvas = Canvas(bitmap)
    drawable.setBounds(0, 0, canvas.width, canvas.height)
    drawable.draw(canvas)
    return bitmap
}

আশা করি এটি সাহায্য করবে


0
Drawable layerDrawable = (Drawable) imageBase.getDrawable();
Bitmap bitmap = Bitmap.createBitmap(layerDrawable.getIntrinsicWidth(),
        layerDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
layerDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
layerDrawable.draw(canvas);  
imageTeste.setImageBitmap(addGradient(bitmap));

0

আপনি যদি নিজের আউটপুটটিকে পছন্দসই আউটপুট আকারে স্কেল করতে সক্ষম হতে চান তবে নীচের স্নিপেটটি ব্যবহার করে দেখুন:

fun getBitmapFromVectorDrawable(context: Context, drawableId: Int, outputSize: OutputSize? = null): Bitmap? {
    var drawable = ContextCompat.getDrawable(context, drawableId) ?: return null
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        drawable = DrawableCompat.wrap(drawable).mutate()
    }

    var targetBitmap: Bitmap
    if (outputSize != null) {
        targetBitmap = Bitmap.createBitmap(outputSize.width,
                outputSize.height, Bitmap.Config.ARGB_8888)
    } else {
        targetBitmap = Bitmap.createBitmap(drawable.intrinsicWidth,
            drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
    }

    val canvas = Canvas(targetBitmap)
    val scaleX =  targetBitmap.width.toFloat()/drawable.intrinsicWidth.toFloat()
    val scaleY =  targetBitmap.height.toFloat()/drawable.intrinsicHeight.toFloat()
    canvas.scale(scaleX, scaleY)
    drawable.draw(canvas)

    return targetBitmap
}

class OutputSize(val width: Int, val height: Int)

0

এটি আপনাকে যে আকারে চায় তাতে বিটম্যাপ দেয়। এছাড়াও, এটির প্রয়োজন নেই এমনদের সাথে আরও ভাল পারফরম্যান্সের জন্য প্রতিটি চিত্রের উপর নির্ভর করে স্বচ্ছতা বজায় রাখতে বা না করার অনুমতি দেয়।

public static Bitmap drawableToBitmap(Resources res, int drawableId,
        int width, int height, boolean keepAlpha) {
    Drawable drawable = res.getDrawable(drawableId);
    Bitmap bmp = createBitmap(width, height, keepAlpha ?
            Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
    Canvas cvs = new Canvas(bmp);
    drawable.setBounds(0, 0, width, height);
    drawable.draw(cvs);
    return bmp;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.