Obraz maskujący (kadrowany) w ramce

83

Posiadam bogatą aplikację interfejsu użytkownika, w której chcę wyświetlać obraz o tak złożonym kształcie

wprowadź opis obrazu tutaj

Teraz chcę przyciąć mój obraz zgodnie z obrazem maski, Właściwie obraz jest dynamiczny i można go zaimportować z aparatu lub galerii (kształt kwadratowy lub prostokątny) i chcę, aby ten obraz pasował do mojej ramki układu, jak powyżej

Więc po prostu zastanawiam się, jak to osiągnąć? Każdy pomysł / wskazówka mile widziana

Maska ramki tła
wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj

W ten sposób

Mohammed Azharuddin Shaikh
źródło

Odpowiedzi:

143

Wreszcie otrzymałem rozwiązanie, zmieniając obraz maski i używając XfermodezBitmap

Maska

wprowadź opis obrazu tutaj

 ImageView mImageView= (ImageView)findViewById(R.id.imageview_id);
 Bitmap original = BitmapFactory.decodeResource(getResources(),R.drawable.content_image);
 Bitmap mask = BitmapFactory.decodeResource(getResources(),R.drawable.mask);
 Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888);
 Canvas mCanvas = new Canvas(result);
 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
 mCanvas.drawBitmap(original, 0, 0, null);
 mCanvas.drawBitmap(mask, 0, 0, paint);
 paint.setXfermode(null);
 mImageView.setImageBitmap(result);
 mImageView.setScaleType(ScaleType.CENTER);
 mImageView.setBackgroundResource(R.drawable.background_frame);

zobacz wyjście

wprowadź opis obrazu tutaj

Źródło można znaleźć tutaj

Mohammed Azharuddin Shaikh
źródło
1
hello @ hotveryspicy, dzięki na przykład kod, bardzo pomogło. Stoję przed jakimś problemem, jakaś mała wskazówka będzie dla mnie długa. Chcę wyciąć bitmapę w jakiś narysowany kształt wielokąta. Moja mapa bitowa tnie w kształcie wielokąta, ale zawartość przyciętej mapy bitowej jest pobierana z lewego górnego rogu, czyli 0,0 oryginalnej mapy bitowej. Chcę mieć zawartość poniżej, gdzie rysowany jest wielokąt.
Dory,
@Nidhi możesz stworzyć skalowaną bitmapę dla tego samego.
Mohammed Azharuddin Shaikh
@hotveryspicy dziękuję za odpowiedź. Właściwie chcę zrobić to samo, co tu podano. stackoverflow.com/questions/15969028/… . Mój problem polega na tym, że przycięta bitmapa jest przycięta od góry po lewej, czyli 0,0. Nie tworzą ścieżki, którą podałem. Umieściłem również kod. Proszę, prowadź mnie, gdzie idę źle
Dory
dzięki @hotveryspicy, dla każdego, kto tego potrzebuje, zrobiłem prosty widelec, który może pomóc skalować obraz do rozmiaru maski: github.com/worker8/MaskImage/tree/master
Jestem
1
Aby przeskalować maskę w celu dopasowania do obrazu, używam następującego wiersza: Bitmap resized = Bitmap.createScaledBitmap (mask, original.getWidth (), original.getHeight (), true); I użyj mCanvas.drawBitmap (original, 0, 0, null); mCanvas.drawBitmap (zmieniony rozmiar, 0, 0, malowanie);
Miguel
5

Korzystanie z biblioteki Picassa i niestandardowej transformacji jest jeszcze łatwiejsze:

MaskTransformation.java:

 * ORIGINAL:
 * Copyright (C) 2015 Wasabeef
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.monori.example.utilities;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;

import com.squareup.picasso.Transformation;

public class MaskTransformation implements Transformation {

    private static Paint mMaskingPaint = new Paint();
    private Context mContext;
    private int mMaskId;

    static {
        mMaskingPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    }

    /**
     * @param maskId If you change the mask file, please also rename the mask file, or Glide will get
     * the cache with the old mask. Because getId() return the same values if using the
     * same make file name. If you have a good idea please tell us, thanks.
     */
    public MaskTransformation(Context context, int maskId) {
        mContext = context.getApplicationContext();
        mMaskId = maskId;
    }

    @Override public Bitmap transform(Bitmap source) {
        int width = source.getWidth();
        int height = source.getHeight();

        Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        Drawable mask = getMaskDrawable(mContext, mMaskId);

        Canvas canvas = new Canvas(result);
        mask.setBounds(0, 0, width, height);
        mask.draw(canvas);
        canvas.drawBitmap(source, 0, 0, mMaskingPaint);

        source.recycle();

        return result;
    }

    @Override public String key() {
        return "MaskTransformation(maskId=" + mContext.getResources().getResourceEntryName(mMaskId)
                + ")";
    }

    public Drawable getMaskDrawable(Context context, int maskId) {
        Drawable drawable = ContextCompat.getDrawable(context, maskId);

        if (drawable == null) {
            throw new IllegalArgumentException("maskId is invalid");
        }

        return drawable;
    }
}

Następnie po prostu zdefiniuj go w linii:

Picasso.with(context)
                    .load(imageUrl)
                    .transform(new MaskTransformation(context, _maskDrawableId))
                    .placeholder(R.drawable.drawableId)
                    .into(imageView);
anthonymonori
źródło
1
     final ImageView mImageView = (ImageView) findViewById(R.id.image);
     mImageView.setBackgroundResource(R.drawable.user_outer_circle_icon);


     mImageView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {


            if(b){
                 mImageView.setBackgroundResource(R.drawable.profil_circle);

                 Bitmap original = BitmapFactory.decodeResource(getResources(),R.drawable.doge);

                 Bitmap mask = BitmapFactory.decodeResource(getResources(),R.drawable.mask_white);

                 Bitmap mask1 = BitmapFactory.decodeResource(getResources(),R.drawable.pencil_bg);

                 original = Bitmap.createScaledBitmap(original, mask.getWidth(),mask.getHeight(), true);

                 Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(),Config.ARGB_8888);
                 Canvas mCanvas = new Canvas(result);
                 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
                 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
                 mCanvas.drawBitmap(original, 0, 0, null);
                 mCanvas.drawBitmap(mask, 0, 0, paint);
                 mCanvas.drawBitmap(mask1, 0, 0, null);
                 Bitmap mask2 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_pencil);
                 mCanvas.drawBitmap(mask2, 0, 0, null);
                 mImageView.setImageBitmap(result);
                 mImageView.setScaleType(ScaleType.FIT_XY);

                 b=false;
             }else{
                 ImageView mImageView = (ImageView) findViewById(R.id.image);
                 Bitmap original = BitmapFactory.decodeResource(getResources(),
                 R.drawable.doge);

                 Bitmap mask = BitmapFactory.decodeResource(getResources(),
                 R.drawable.mask_white);

                 original = Bitmap.createScaledBitmap(original, mask.getWidth(),
                 mask.getHeight(), true);

                 Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(),
                 Config.ARGB_8888);
                 Canvas mCanvas = new Canvas(result);
                 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
                 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
                 mCanvas.drawBitmap(original, 0, 0, null);
                 mCanvas.drawBitmap(mask, 0, 0, paint);
                 paint.setXfermode(null);
                 mImageView.setImageBitmap(result);
                 mImageView.setScaleType(ScaleType.FIT_XY);
                // mImageView.setBackgroundResource(R.drawable.user_outer_circle_icon);
                 b= true;


             }


        }
    });
Prashant
źródło
0

W tym przykładzie jego element podrzędny (widok obrazu) maskuje maskę „animation_mask”

<com.christophesmet.android.views.maskableframelayout.MaskableFrameLayout
android:id="@+id/frm_mask_animated"
android:layout_width="100dp"
app:porterduffxfermode="DST_IN"
app:mask="@drawable/animation_mask"
android:layout_height="100dp">

<ImageView android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:scaleType="centerCrop"
           android:src="@drawable/unicorn"/>

sprawdź ten link do gita

Lalli
źródło