একটি চিত্রদর্শন সেট করতে অ্যান্ড্রয়েডে দুটি চিত্রকে ওভারলে করুন


100

আমি আমার অ্যাপ্লিকেশনটিতে দুটি চিত্রকে ওভারলে করার চেষ্টা করছি তবে এগুলি আমার canvas.setBitmap()লাইনে ক্র্যাশ হয়ে গেছে বলে মনে হচ্ছে । আমি কি ভুল করছি?

private void test() {
    Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.t);
    Bitmap mBitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.tt);
    Bitmap bmOverlay = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());
    Canvas canvas = new Canvas();
    canvas.setBitmap(bmOverlay);
    canvas.drawBitmap(mBitmap, new Matrix(), null);
    canvas.drawBitmap(mBitmap2, new Matrix(), null);
    testimage.setImageBitmap(bmOverlay);
}

: মত এই হিসাবে ভাল একটি framelayout ব্যবহার করতে পারেন, stackoverflow.com/a/11658554/586484
Lysogen

উত্তর:


235

আপনি জটিল ক্যানভাস ম্যানিপুলেশনটি এড়িয়ে যেতে পারেন এবং ব্যবহার করে ড্রওএবলের সাথে এটি পুরোপুরি করতে পারেন LayerDrawable। আপনার দুটি পছন্দের মধ্যে একটি রয়েছে: আপনি এটি এক্সএমএলে এটি সংজ্ঞায়িত করতে পারেন তবে কেবল চিত্রটি সেট করুন অথবা আপনি LayerDrawableকোডটিতে একটি গতিশীল কনফিগার করতে পারেন ।

সমাধান # 1 (এক্সএমএল মাধ্যমে):

একটি নতুন অঙ্কনযোগ্য এক্সএমএল ফাইল তৈরি করুন, আসুন এটি কল করুন layer.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/t" />
    <item android:drawable="@drawable/tt" />
</layer-list>

এখন সেই অঙ্কনযোগ্য ব্যবহার করে চিত্রটি সেট করুন:

testimage.setImageDrawable(getResources().getDrawable(R.layout.layer));

সমাধান # 2 (গতিশীল):

Resources r = getResources();
Drawable[] layers = new Drawable[2];
layers[0] = r.getDrawable(R.drawable.t);
layers[1] = r.getDrawable(R.drawable.tt);
LayerDrawable layerDrawable = new LayerDrawable(layers);
testimage.setImageDrawable(layerDrawable);

(আমি এই কোডটি পরীক্ষা করি নি তাই ভুল হতে পারে তবে এই সাধারণ রূপরেখার কাজ করা উচিত))


4
ধন্যবাদ, এটি কাজ করেছে! যদিও একটি টাইপ, অন্য কেউ কোডটি ব্যবহার করে: LayerDrawable স্তরগুলি = = নতুন লেয়ারড্রেবল (স্তর); সাক্ষ্যদান.সেটমেজড্র্যাবেবল (স্তরসমূহ 2);
জন

4
স্থান বাঁচাতে এবং চিত্রগুলি পুনরায় ব্যবহার করার দুর্দান্ত উপায়। এছাড়াও, আপনি .xML ফাইলের মধ্যে একটি স্তরকে নিয়ন্ত্রণ করতে অ্যান্ড্রয়েড: বাম, অ্যান্ড্রয়েড: ডান, অ্যান্ড্রয়েড: শীর্ষ এবং অ্যান্ড্রয়েড: ডাউন ব্যবহার করতে পারেন can
zabawaba99

আমি এটি একটি চিত্রের পিছনে একটি বৃত্তাকার আকৃতি আঁকার জন্য আঁকা ব্যবহার করেছিলাম, খুব সুন্দর সমাধান!
ড্যানিয়েল উইলসন

4
কর্মসূচিগতভাবে একা [1] স্তরগুলি আড়াল করার কোনও উপায় আছে কি? আমি শীর্ষে অ্যাজ্যাক্স লোডার স্তর সহ একটি চিত্র স্তর প্রদর্শন করতে চাই। কিছু সময় পরে আমি একাই এজ্যাক্স লোডারটি আড়াল করতে চাই। যেকোনো পরামর্শ?
হরিশন্নাম

4
আমার প্রয়োজনের জন্য ভাল কাজ করে (আমি কোড পদ্ধতির ব্যবহার করেছি)। আমার কাছে বেশ কয়েকটি 'টাইলস' রয়েছে যা ব্যবহারকারী অ্যাপটির চারপাশে নেভিগেট করতে ট্যাপ করে। এই পদ্ধতির সাহায্যে আমি একটি একক পটভূমি চিত্র (সমস্ত টাইলের কাছে সাধারণ) এবং অসংখ্য ফোরগ্রাউন্ড চিত্র (স্বচ্ছ ব্যাকগ্রাউন্ড সহ) রাখতে সক্ষম হয়েছি যা আমি রানটাইমে লোড করতে পারি। এই উত্তর ছাড়া লেয়ারড্রেবলের দিকে নজর দিতেন না :-)
দিলবার্ট ডেভ

10

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

লোগোটি শাজাম পটভূমির চিত্রের শীর্ষে চলেছে।

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/widget30"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<ImageView
android:id="@+id/widget39"
android:layout_width="219px"
android:layout_height="225px"
android:src="@drawable/shazam_bkgd"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
>
</ImageView>
<ImageView
android:id="@+id/widget37"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/shazam_logo"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
>
</ImageView>
</RelativeLayout>

6

সমস্যাটি সমাধান করতে আপনি নীচের কোডটি ব্যবহার করতে পারেন বা ডেমো ডাউনলোড

প্রতিটি পরিচালনা করার জন্য দুটি ফাংশন তৈরি করুন।

প্রথমে, ক্যানভাসটি অঙ্কিত হয় এবং চিত্রগুলি বিন্দু থেকে একে অপরের উপরে আঁকা হয় (0,0)

বাটনে ক্লিক করুন

public void buttonMerge(View view) {

        Bitmap bigImage = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
        Bitmap smallImage = BitmapFactory.decodeResource(getResources(), R.drawable.img2);
        Bitmap mergedImages = createSingleImageFromMultipleImages(bigImage, smallImage);

        img.setImageBitmap(mergedImages);
    }

একটি ওভারলে তৈরি করার জন্য ফাংশন।

private Bitmap createSingleImageFromMultipleImages(Bitmap firstImage, Bitmap secondImage){

    Bitmap result = Bitmap.createBitmap(firstImage.getWidth(), firstImage.getHeight(), firstImage.getConfig());
    Canvas canvas = new Canvas(result);
    canvas.drawBitmap(firstImage, 0f, 0f, null);
    canvas.drawBitmap(secondImage, 10, 10, null);
    return result;
}

আরও পড়ুন


2

এটি কিছুটা দেরি করে উত্তর, তবে এটি পিকাসো ব্যবহার করে ইউআরএল থেকে চিত্রগুলি মার্জ করে coversেকে দেয়

মার্জআইমেজভিউ

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;

import java.io.IOException;
import java.util.List;

public class MergeImageView extends ImageView {

    private SparseArray<Bitmap> bitmaps = new SparseArray<>();
    private Picasso picasso;
    private final int DEFAULT_IMAGE_SIZE = 50;
    private int MIN_IMAGE_SIZE = DEFAULT_IMAGE_SIZE;
    private int MAX_WIDTH = DEFAULT_IMAGE_SIZE * 2, MAX_HEIGHT = DEFAULT_IMAGE_SIZE * 2;
    private String picassoRequestTag = null;

    public MergeImageView(Context context) {
        super(context);
    }

    public MergeImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MergeImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public MergeImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public boolean isInEditMode() {
        return true;
    }

    public void clearResources() {
        if (bitmaps != null) {
            for (int i = 0; i < bitmaps.size(); i++)
                bitmaps.get(i).recycle();
            bitmaps.clear();
        }
        // cancel picasso requests
        if (picasso != null && AppUtils.ifNotNullEmpty(picassoRequestTag))
            picasso.cancelTag(picassoRequestTag);
        picasso = null;
        bitmaps = null;
    }

    public void createMergedBitmap(Context context, List<String> imageUrls, String picassoTag) {
        picasso = Picasso.with(context);
        int count = imageUrls.size();
        picassoRequestTag = picassoTag;

        boolean isEven = count % 2 == 0;
        // if url size are not even make MIN_IMAGE_SIZE even
        MIN_IMAGE_SIZE = DEFAULT_IMAGE_SIZE + (isEven ? count / 2 : (count / 2) + 1);
        // set MAX_WIDTH and MAX_HEIGHT to twice of MIN_IMAGE_SIZE
        MAX_WIDTH = MAX_HEIGHT = MIN_IMAGE_SIZE * 2;
        // in case of odd urls increase MAX_HEIGHT
        if (!isEven) MAX_HEIGHT = MAX_WIDTH + MIN_IMAGE_SIZE;

        // create default bitmap
        Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_wallpaper),
                MIN_IMAGE_SIZE, MIN_IMAGE_SIZE, false);

        // change default height (wrap_content) to MAX_HEIGHT
        int height = Math.round(AppUtils.convertDpToPixel(MAX_HEIGHT, context));
        setMinimumHeight(height * 2);

        // start AsyncTask
        for (int index = 0; index < count; index++) {
            // put default bitmap as a place holder
            bitmaps.put(index, bitmap);
            new PicassoLoadImage(index, imageUrls.get(index)).execute();
            // if you want parallel execution use
            // new PicassoLoadImage(index, imageUrls.get(index)).(AsyncTask.THREAD_POOL_EXECUTOR);
        }
    }

    private class PicassoLoadImage extends AsyncTask<String, Void, Bitmap> {

        private int index = 0;
        private String url;

        PicassoLoadImage(int index, String url) {
            this.index = index;
            this.url = url;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            try {
                // synchronous picasso call
                return picasso.load(url).resize(MIN_IMAGE_SIZE, MIN_IMAGE_SIZE).tag(picassoRequestTag).get();
            } catch (IOException e) {
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap output) {
            super.onPostExecute(output);
            if (output != null)
                bitmaps.put(index, output);

            // create canvas
            Bitmap.Config conf = Bitmap.Config.RGB_565;
            Bitmap canvasBitmap = Bitmap.createBitmap(MAX_WIDTH, MAX_HEIGHT, conf);
            Canvas canvas = new Canvas(canvasBitmap);
            canvas.drawColor(Color.WHITE);

            // if height and width are equal we have even images
            boolean isEven = MAX_HEIGHT == MAX_WIDTH;
            int imageSize = bitmaps.size();
            int count = imageSize;

            // we have odd images
            if (!isEven) count = imageSize - 1;
            for (int i = 0; i < count; i++) {
                Bitmap bitmap = bitmaps.get(i);
                canvas.drawBitmap(bitmap, bitmap.getWidth() * (i % 2), bitmap.getHeight() * (i / 2), null);
            }
            // if images are not even set last image width to MAX_WIDTH
            if (!isEven) {
                Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmaps.get(count), MAX_WIDTH, MIN_IMAGE_SIZE, false);
                canvas.drawBitmap(scaledBitmap, scaledBitmap.getWidth() * (count % 2), scaledBitmap.getHeight() * (count / 2), null);
            }
            // set bitmap
            setImageBitmap(canvasBitmap);
        }
    }
}

এক্সএমএল

<com.example.MergeImageView
    android:id="@+id/iv_thumb"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

উদাহরণ

List<String> urls = new ArrayList<>();
String picassoTag = null;
// add your urls
((MergeImageView)findViewById(R.id.iv_thumb)).
        createMergedBitmap(MainActivity.this, urls,picassoTag);

1

এটি আমার সমাধান:

    public Bitmap Blend(Bitmap topImage1, Bitmap bottomImage1, PorterDuff.Mode Type) {

        Bitmap workingBitmap = Bitmap.createBitmap(topImage1);
        Bitmap topImage = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);

        Bitmap workingBitmap2 = Bitmap.createBitmap(bottomImage1);
        Bitmap bottomImage = workingBitmap2.copy(Bitmap.Config.ARGB_8888, true);

        Rect dest = new Rect(0, 0, bottomImage.getWidth(), bottomImage.getHeight());
        new BitmapFactory.Options().inPreferredConfig = Bitmap.Config.ARGB_8888;
        bottomImage.setHasAlpha(true);
        Canvas canvas = new Canvas(bottomImage);
        Paint paint = new Paint();

        paint.setXfermode(new PorterDuffXfermode(Type));

        paint.setFilterBitmap(true);
        canvas.drawBitmap(topImage, null, dest, paint);
        return bottomImage;
    }

ব্যবহার:

imageView.setImageBitmap(Blend(topBitmap, bottomBitmap, PorterDuff.Mode.SCREEN));

বা

imageView.setImageBitmap(Blend(topBitmap, bottomBitmap, PorterDuff.Mode.OVERLAY));

এবং ফলাফল:

ওভারলে মোড: ওভারলে মোড

স্ক্রীন মোডে: স্ক্রীন মোডে


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