কোনও দৃশ্য অ্যান্ড্রয়েডে প্রদর্শন না করে বিটম্যাপে রূপান্তর করা হচ্ছে?


133

আমার ঠিক কী করা দরকার তা বোঝানোর চেষ্টা করব।

আমার কাছে 3, আলাদা আলাদা স্ক্রিন রয়েছে যা এ, বি, সি বলে। হোম স্ক্রিন বলে আরেকটি পর্দা রয়েছে যেখানে 3 টি স্ক্রিনের বিটম্যাপটি গ্যালারী ভিউতে প্রদর্শিত হওয়া উচিত এবং ব্যবহারকারী কোন দৃষ্টিতে যেতে চান তা নির্বাচন করতে পারেন।

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

সুতরাং, আমি হোমস্ক্রিন থেকে অন্য ক্রিয়াকলাপ কল করতে পারি এবং এটি প্রদর্শিত না করে কেবল সেই স্ক্রিনের বিটম্যাপটি পাই। উদাহরণস্বরূপ, বলুন যে আমি কেবল হোমস্ক্রিন কল করি এবং এটি ক্রিয়াকলাপ এ, বি, সি কল করে এবং এ, বি, সি এর ক্রিয়াকলাপগুলির কোনওটিই প্রদর্শিত হয় না। এটি কেবল getDrawingCache () দ্বারা সেই স্ক্রিনের বিটম্যাপ দেয়। এবং তারপরে আমরা হোমস্ক্রিনে গ্যালারী ভিউতে bit বিটম্যাপগুলি প্রদর্শন করতে পারি।

আমি আশা করি আমি খুব স্পষ্টভাবে সমস্যাটি ব্যাখ্যা করেছি।

এটি যদি সম্ভব হয় তবে আমাকে জানান know


1
আমি পুরোপুরি নিশ্চিত নই, তবে আমি মনে করি আপনি এটি করতে সক্ষম হবেন না। সমস্যাটি হ'ল ক্রিয়াকলাপগুলি ব্যবহারকারীর কাছে প্রদর্শিত হয়। আপনি ক্রিয়াকলাপটি শুরু করতে পারেন এবং তারপরে তা অবিলম্বে এটি আড়াল করতে পারেন তবে ক্রিয়াকলাপটি এখনও স্প্লিট-সেকেন্ডের জন্য ব্যবহারকারীর কাছে দৃশ্যমান হবে। এটি লক্ষ্য করার জন্য যথেষ্ট দীর্ঘ দেখানো হয়েছে যাতে বেশ কয়েকবার স্ক্রিনের ঝাঁকুনি থাকা অ্যাপ্লিকেশনটিকে পেশাদারিহীন দেখায়। তবে এটি সম্ভবত প্রদর্শিত হতে পারে যে কোনও ক্রিয়াকলাপটি প্রদর্শন না করেই শুরু করার জন্য একটি আদেশ রয়েছে; এটির উপস্থিতি থাকলে আমি কেবল তার সম্পর্কে জানি না।
স্টিভ হ্যালি

5
আসলে, আমি এটি করতে সক্ষম হয়েছি।
সানিল

ওহ, আপনি কীভাবে সেই ক্রিয়াকলাপটিকে কল করতে পারেন তবে এটি প্রদর্শন না করে? আমি কী বর্তমান কার্যকলাপের লেআউটটিকে বিটম্যাপ তৈরি করতে টেমপ্লেট হিসাবে বিভিন্ন বিষয়বস্তু খাওয়ানোর সময় নিতে পারি?
zionpi

: এই পোস্টে উত্তর চেক, আমি সমাধান কোন ধরণের পাওয়া stackoverflow.com/questions/36424381/...
Wackaloon

উত্তর:


212

এটি করার একটি উপায় আছে। আপনাকে একটি বিটম্যাপ এবং ক্যানভাস তৈরি করতে হবে এবং ভিউ কল করুন draড্র (ক্যানভাস);

কোডটি এখানে:

public static Bitmap loadBitmapFromView(View v) {
    Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);                
    Canvas c = new Canvas(b);
    v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
    v.draw(c);
    return b;
}

যদি ভিউটি প্রদর্শিত না হয় তবে এর আকারটি শূন্য হবে। এটি এটির মতো পরিমাপ করা সম্ভব:

if (v.getMeasuredHeight() <= 0) {
    v.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
    v.draw(c);
    return b;
}

সম্পাদনা: এই পোস্ট অনুসারে , মান হিসাবে পাসিং কোনও ভাল করতে হবে নাWRAP_CONTENTmakeMeasureSpec() (যদিও কিছু দর্শন শ্রেণীর জন্য এটি কাজ করে), এবং প্রস্তাবিত পদ্ধতিটি হ'ল:

// Either this
int specWidth = MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.AT_MOST);
// Or this
int specWidth = MeasureSpec.makeMeasureSpec(0 /* any */, MeasureSpec.UNSPECIFIED);
view.measure(specWidth, specWidth);
int questionWidth = view.getMeasuredWidth();

1
আমি এটি চেষ্টা করেছিলাম তবে যা পেয়েছি তা একটি আধা স্বচ্ছ কালো বাক্স। বিটম্যাপ অঙ্কনের জন্য প্রস্তুত হওয়ার জন্য আমার কি ভিউতে কিছু করার প্রয়োজন?
ববকে 4

4
এটি v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());সঠিকভাবে কাজ করার জন্য আমাকে আসলে এটি পরিবর্তন করতে হয়েছিল তবে কোডের জন্য ধন্যবাদ :)
অগ্রে

3
আমাকে v.getLayoutParams ()। প্রশস্ত এবং উচ্চতার জন্য অনুরূপ পরিবর্তে v.getWidth () ব্যবহার করতে হয়েছিল। অন্যথায়, এখন কাজ।
ডেভিড ম্যানপারল

1
আমি ব্যবহৃত v.measure(0, 0); v.getMeasuredWidth(); v.getMeasuredHeight();
ব্রাইস গাবিন

7
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);আরও ভাল কাজ করে
পিয়েরে

29

এখানে আমার সমাধান:

public static Bitmap getBitmapFromView(View view) {
    Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(returnedBitmap);
    Drawable bgDrawable =view.getBackground();
    if (bgDrawable!=null) 
        bgDrawable.draw(canvas);
    else 
        canvas.drawColor(Color.WHITE);
    view.draw(canvas);
    return returnedBitmap;
}

উপভোগ করুন :)


ধন্যবাদ। উচ্চতা একটি নির্দিষ্ট মানের বাইরে থাকলে আমার কিছু ডিভাইসে সমস্যা ছিল। আমি পুরোপুরি পরীক্ষা করে দেখিনি তবে এটি সমাধান করতে দেখা যাচ্ছে।
BMF

22

এটা চেষ্টা কর,

/**
 * Draw the view into a bitmap.
 */
public static Bitmap getViewBitmap(View v) {
    v.clearFocus();
    v.setPressed(false);

    boolean willNotCache = v.willNotCacheDrawing();
    v.setWillNotCacheDrawing(false);

    // Reset the drawing cache background color to fully transparent
    // for the duration of this operation
    int color = v.getDrawingCacheBackgroundColor();
    v.setDrawingCacheBackgroundColor(0);

    if (color != 0) {
        v.destroyDrawingCache();
    }
    v.buildDrawingCache();
    Bitmap cacheBitmap = v.getDrawingCache();
    if (cacheBitmap == null) {
        Log.e(TAG, "failed getViewBitmap(" + v + ")", new RuntimeException());
        return null;
    }

    Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

    // Restore the view
    v.destroyDrawingCache();
    v.setWillNotCacheDrawing(willNotCache);
    v.setDrawingCacheBackgroundColor(color);

    return bitmap;
}

আমি আমার প্রধান ক্রিয়াকলাপ থেকে এটি কীভাবে ব্যবহার করব?
Si8

এটি
অবচয়

20

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

আমার মামলার কাজটি এখানে শেষ হয়েছে। একটি সতর্কতা সঙ্গে, তবে। কল করার আগে getViewBitmap(View)আমি আমার দৃষ্টিভঙ্গি স্ফীত করেছিলাম এবং এটি পরিচিত মাত্রাগুলি সহ বিন্যাস করতে বলেছিলাম। এটির প্রয়োজন ছিল যেহেতু আমার ভিউ লেআউটটি কন্টেন্টের ভিতরে না রেখে যতক্ষণ না এটি শূন্য উচ্চতা / প্রস্থ তৈরি করে।

View view = LayoutInflater.from(context).inflate(layoutID, null);
//Do some stuff to the view, like add an ImageView, etc.
view.layout(0, 0, width, height);

Bitmap getViewBitmap(View view)
{
    //Get the dimensions of the view so we can re-layout the view at its current size
    //and create a bitmap of the same size 
    int width = view.getWidth();
    int height = view.getHeight();

    int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
    int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);

    //Cause the view to re-layout
    view.measure(measuredWidth, measuredHeight);
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

    //Create a bitmap backed Canvas to draw the view into
    Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);

    //Now that the view is laid out and we have a canvas, ask the view to draw itself into the canvas
    view.draw(c);

    return b;
}

আমার জন্য "ম্যাজিক সস" এখানে পাওয়া গেছে: https://groups.google.com/forum/#!topic/android-developers/BxIBAOeTA1Q

চিয়ার্স,

লেভি


চিয়ার্স! দেখে মনে হচ্ছে যে তাদের প্রদর্শিত হওয়ার জন্য বিন্যাসে যে কোনও পরিবর্তন হওয়ার পরে একজনকে অবশ্যই পরিমাপ কল করতে হবে এবং
অনুরোধই

1
এই সমাধানের জন্য ধন্যবাদ! আমারও একই সমস্যা ছিল। আমি আমার দৃষ্টিভঙ্গি জনপ্রিয় করার আগে ব্যবহার করছিলাম measure()এবং এর layout()ফলে আমার অদ্ভুত ফলাফল হয়েছিল। এই কলগুলি নামানো, উপরে createBitmap()এটি আমার জন্য স্থির!
সোভেন জ্যাকবস

6

অ্যান্ড্রয়েড কেটিএক্সে একটি দুর্দান্ত কোটলিন এক্সটেনশন ফাংশন রয়েছে: View.drawToBitmap(Bitmap.Config)


3
বিন্যাসে ভিউ উপস্থাপন না করা হলে এটি কাজ করবে না। ত্রুটি: "বেআইনী স্ট্যাটেক্সটেক্সপশন: ড্রটওবিটম্যাপ () কল করার আগে ভিউটি আলাদা করা দরকার"
ভ্যাল

2

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

View view="some view instance";        
view.setDrawingCacheEnabled(true);
Bitmap bitmap=view.getDrawingCache();
view.setDrawingCacheEnabled(false);

আপডেট
getDrawingCache() পদ্ধতিটি এপিআই স্তরের ২৮ এ অবমূল্যায়ন করা হয়েছে So


1
getDrawingCacheবর্তমানে হ্রাস করা হয়েছে।
ডেভিড মিগুয়েল

0

আমি মনে করি এটি কিছুটা ভাল:

/**
 * draws the view's content to a bitmap. code initially based on :
 * http://nadavfima.com/android-snippet-inflate-a-layout-draw-to-a-bitmap/
 */
@Nullable
public static Bitmap drawToBitmap(final View viewToDrawFrom, int width, int height) {
    boolean wasDrawingCacheEnabled = viewToDrawFrom.isDrawingCacheEnabled();
    if (!wasDrawingCacheEnabled)
        viewToDrawFrom.setDrawingCacheEnabled(true);
    if (width <= 0 || height <= 0) {
        if (viewToDrawFrom.getWidth() <= 0 || viewToDrawFrom.getHeight() <= 0) {
            viewToDrawFrom.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            width = viewToDrawFrom.getMeasuredWidth();
            height = viewToDrawFrom.getMeasuredHeight();
        }
        if (width <= 0 || height <= 0) {
            final Bitmap bmp = viewToDrawFrom.getDrawingCache();
            final Bitmap result = bmp == null ? null : Bitmap.createBitmap(bmp);
            if (!wasDrawingCacheEnabled)
                viewToDrawFrom.setDrawingCacheEnabled(false);
            return result;
        }
        viewToDrawFrom.layout(0, 0, width, height);
    } else {
        viewToDrawFrom.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
        viewToDrawFrom.layout(0, 0, viewToDrawFrom.getMeasuredWidth(), viewToDrawFrom.getMeasuredHeight());
    }
    final Bitmap drawingCache = viewToDrawFrom.getDrawingCache();
    final Bitmap bmp = ThumbnailUtils.extractThumbnail(drawingCache, width, height);
    final Bitmap result = bmp == null || bmp != drawingCache ? bmp : Bitmap.createBitmap(bmp);
    if (!wasDrawingCacheEnabled)
        viewToDrawFrom.setDrawingCacheEnabled(false);
    return result;
}

উপরের কোডটি ব্যবহার করে, যদি আপনি নিজেই ভিউর মধ্যে একটিটি ব্যবহার করতে চান তবে আপনাকে বিটম্যাপের আকার নির্দিষ্ট করতে হবে না (প্রস্থ এবং উচ্চতার জন্য 0 ব্যবহার করুন)।

এছাড়াও, আপনি যদি বিশেষ ভিউগুলি (সারফেসভিউ, সারফেস বা উইন্ডো, উদাহরণস্বরূপ) বিটম্যাপে রূপান্তর করতে চান তবে আপনার পরিবর্তে পিক্সেলকপি ক্লাস ব্যবহার করা উচিত । যদিও এটির 24 ও ততোধিক এপিআই দরকার requires আমি জানি না যে এটি আগে কীভাবে করা যায়।


কোনও ধারণা, কোনও টেক্সটভিউ বিটম্যাপে যুক্ত করা হয়নি। শুধুমাত্র ইমেজভিউগুলি যুক্ত করা হয়েছে।
খেমরাজ

@ ਖੇেমরাজ আমি প্রশ্নটি বুঝতে পারি না।
অ্যান্ড্রয়েড বিকাশকারী

এটি আমার দোষ ছিল আমার টেক্সটভিউ বিটম্যাপে ছিল না। কারণ আমি হালকা রঙের থিম প্রয়োগ করেছি, উত্তরের জন্য ধন্যবাদ।
খেমরাজ

1
@ খেমরাজ দুঃখিত তবে আমি এখনও বুঝতে পারি না। ঠিক আছে এখন?
অ্যান্ড্রয়েড বিকাশকারী

হ্যাঁ ভাই, আপনি কেন আমাকে পাচ্ছেন না আমি তা জানি না :)। আমার বিন্যাসে একটি টেক্সটভিউ ছিল যা আমি বিটম্যাপে রূপান্তর করতে চেয়েছিলাম। লেআউটের একটি ইমেজভিউ এবং একটি টেক্সটভিউ ছিল। ইমেজভিউ বিটম্যাপে রূপান্তরিত হচ্ছিল। তবে টেক্সটভিউ বিটম্যাপে উপস্থিত হচ্ছিল না। সমস্যা ছিল। এর পরে আমি বুঝতে পারি আমার একটি থিম প্রয়োগ হয়েছে যা পাঠ্যদর্শন পাঠ্যের রঙকে সাদা করে তুলছে। আমি এটা ঠিক করেছি. এবং এখন সব ঠিক আছে। ধন্যবাদ।
খেমরাজ

0

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

 private Bitmap createBitmapFromLayout(View tv) {      
    int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    tv.measure(spec, spec);
    tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
    Bitmap b = Bitmap.createBitmap(tv.getMeasuredWidth(), tv.getMeasuredWidth(),
            Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    c.translate((-tv.getScrollX()), (-tv.getScrollY()));
    tv.draw(c);
    return b;
}

কল করার পদ্ধতি:

Bitmap src = createBitmapFromLayout(View.inflate(this, R.layout.sample, null)/* or pass your view object*/);

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