Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a custom Camera with live Stickers

I am making a custom camera with face detection, which works successfully.

But I want to add stickers like to the recorded/previewed face. The location of the eyes is used to properly size and place a hat, glasses, and tie etc. on the Preview.

The Face Detection with the FaceOverlayView

public class FaceOverlayView extends View {
    private Paint mPaint;
    private Paint mTextPaint;
    private int mDisplayOrientation;
    private int mOrientation;
    private Face[] mFaces;

    public FaceOverlayView(Context context) {
        super(context);
        initialize();
    }

    private void initialize() {
        // We want a green box around the face:
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.GREEN);
        mPaint.setAlpha(128);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setDither(true);
        mTextPaint.setTextSize(20);
        mTextPaint.setColor(Color.GREEN);
        mTextPaint.setStyle(Paint.Style.FILL);
    }

    public void setFaces(Face[] faces) {
        mFaces = faces;
        invalidate();
    }

    public void setOrientation(int orientation) {
        mOrientation = orientation;
    }

    public void setDisplayOrientation(int displayOrientation) {
        mDisplayOrientation = displayOrientation;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mFaces != null && mFaces.length > 0) {
            Matrix matrix = new Matrix();
            Util.prepareMatrix(matrix, false, mDisplayOrientation, getWidth(), getHeight());
            canvas.save();
            matrix.postRotate(mOrientation);
            canvas.rotate(-mOrientation);
            RectF rectF = new RectF();
            for (Face face : mFaces) {
                rectF.set(face.rect);
                matrix.mapRect(rectF);
                canvas.drawRect(rectF, mPaint);
                canvas.drawText("Score " + face.score, rectF.right, rectF.top, mTextPaint);
            }
            canvas.restore();
        }
    }
}

I want to add the hat and sunglasses on the preview like a similar in the Play Store, Face 28:

enter image description here


More Info.

I am using for MoodMeSDK to detect the eyes and mouth

The result is 66 Points:

enter image description here

I want put sunglasses, caps, lips, etc. on the face. In the Face28 APK using the SVG file for the face stickers.

like image 225
Arjun saini Avatar asked Nov 07 '16 06:11

Arjun saini


People also ask

Where are stickers in Samsung camera?

Open the Camera app > Tap AR EMOJI. Step 2. Select a sticker. Look at the camera and the emoji will repeat your actions.


1 Answers

I have done something almost similar to this before. So here's how you need to do this: first you need to locate the points relative to the View's Rectangle, for example if you want to place a hat, first pin-point head and relative rectangle of hat based on the CameraView, then place the hat on that coordinate. This is the easy part. The hard part is saving the image. for this you need to save width and length of CameraView and stickers on it and their locations on CameraView. Then you capture the image and get a Bitmap/Drawable. You will most likely get different sizes for produced bitmap than CameraView so you need to re-calculate the coordinate of stickers on this bitmap based on it's w/h to the CameraView and merge stickers on new coordinates and then save it. It is not easy but it is possible as I did it.

Here's my code(in my case sticker was being placed in center of picture):

/**
 * Created by Mohammad Erfan Molaei on 9/26/16.
 */
public class CaptureActivity extends AppCompatActivity implements
        ActivityCompat.OnRequestPermissionsResultCallback {
private static final String TAG = "CaptureActivity";


private FloatingActionButton takePicture;

private int mCurrentFlash;

private CameraView mCameraView;

private int cameraWidth;

private int cameraHeight;

private int drawableWidth;

private int drawableHeight;

private Handler mBackgroundHandler;

private boolean selectedBrand;
@Override
public void setTheme(int resId) {
    selectedBrand = getSharedPreferences(getString(R.string.brand_pref), MODE_PRIVATE)
            .getBoolean(getString(R.string.selected_brand), true);
    super.setTheme(selectedBrand ? R.style.AppTheme_CaptureTheme : R.style.AppTheme_CaptureTheme2);
}

private String itemID = null;

private View.OnClickListener mOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.take_picture:
                if (mCameraView != null) {
                    mCameraView.takePicture();
                    takePicture.setEnabled(false);
                }
                break;

            case R.id.scale_up_btn:
                scaleUpImage();
                break;

            case R.id.scale_down_btn:
                scaleDownImage();
                break;
        }
    }
};

private void scaleUpImage() {
    if (mCameraView != null) {
        SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);

        /*Log.e(TAG, "scaleDownImage: oldWidth: " + imageView.getLayoutParams().width +
                ", oldHeight: " + imageView.getLayoutParams().height);
        Log.e(TAG, "scaleDownImage: newWidth2B: " + (imageView.getLayoutParams().width * 1.1f) +
                ", newHeight2B: " + ((1.1f * imageView.getLayoutParams().width) *
                imageView.getLayoutParams().height /
                imageView.getLayoutParams().width));
        Log.e(TAG, "cameraWidth: " + mCameraView.getLayoutParams().width );
sdasd*/
            if (imageView.getWidth() * 1.1f > mCameraView.getWidth() ||
                    ((1.1f * imageView.getWidth()) *
                            imageView.getHeight() /
                            imageView.getWidth()) > mCameraView.getHeight())
                return;



        imageView.getLayoutParams().height = (int) ((1.1f * imageView.getWidth()) *
                imageView.getHeight() /
                imageView.getWidth());
        imageView.getLayoutParams().width = (int) (imageView.getWidth() * 1.1f);

        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        imageView.requestLayout();
        /*drawableWidth = dp2px(imageView.getWidth());
        drawableHeight = dp2px(imageView.getHeight());*/

    }
}

private void scaleDownImage() {
    if (mCameraView != null) {
        SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);

        if (imageView.getWidth() * 0.9f > mCameraView.getWidth() ||
                ((0.9f * imageView.getWidth()) *
                        imageView.getHeight() /
                        imageView.getWidth()) > mCameraView.getHeight())
            return;



        imageView.getLayoutParams().height = (int) ((0.9f * imageView.getWidth()) *
                imageView.getHeight() /
                imageView.getWidth());
        imageView.getLayoutParams().width = (int) (imageView.getWidth() * 0.9f);

        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        imageView.requestLayout();
        /*drawableWidth = dp2px(imageView.getWidth());
        drawableHeight = dp2px(imageView.getHeight());*/

    }
}


private void rotateImage() {
    if (mCameraView != null) {
        SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
        /*Drawable mDrawable = imageView.getDrawable();
        int mDrawableWidth = mDrawable.getBounds().width();
        int mDrawableHeight = mDrawable.getBounds().height();*/

        int newWidth = imageView.getHeight();
        int newHeight = imageView.getWidth();
        float scaleFactor = 1;
        /*Log.e(TAG, "rotateImage: prevWidth: " + newHeight + ", prevHeight: " + newWidth);
        Log.e(TAG, "rotateImage: cameraWidth: " + mCameraView.getWidth() );*/
        if (newWidth > mCameraView.getWidth() ) {
            scaleFactor = (float)newWidth / (float)mCameraView.getWidth();

            newWidth = mCameraView.getWidth();
            newHeight *= scaleFactor;

        } else if (newHeight > mCameraView.getHeight() ) {
            scaleFactor = (float)newHeight / (float)mCameraView.getHeight();
            newHeight = mCameraView.getHeight();
            newWidth *= scaleFactor;
        }
        Log.e(TAG, "rotateImage: scaleFactor: " + scaleFactor);



        imageView.setRotation(imageView.getRotation() + 90);
        imageView.getLayoutParams().height = newHeight;
        imageView.getLayoutParams().width = newWidth;
        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        imageView.requestLayout();
        /*drawableWidth = dp2px(imageView.getWidth());
        drawableHeight = dp2px(imageView.getHeight());*/
        //imageView.setImageDrawable(getRotatedDrawable(imageView));


        /*Bitmap bitmapOrg = drawableToBitmap(imageView.getDrawable());
        // createa matrix for the manipulation
        Matrix matrix = imageView.getImageMatrix();

        int width = bitmapOrg.getWidth();
        int height = bitmapOrg.getHeight();



        // rotate the Bitmap
        matrix.postRotate(90);

        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
                width, height, matrix, true);

        // make a Drawable from Bitmap to allow to set the BitMap
        // to the ImageView, ImageButton or what ever
        BitmapDrawable bmd = new BitmapDrawable(getResources(), resizedBitmap);

        // set the Drawable on the ImageView
        imageView.setImageDrawable(bmd);*/

    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_capture);
    mCameraView = (CameraView) findViewById(R.id.camera);
    if (mCameraView != null) {
        mCameraView.addCallback(mCallback);
    }
    takePicture = (FloatingActionButton) findViewById(R.id.take_picture);
    if (takePicture != null) {
        takePicture.setOnClickListener(mOnClickListener);
    }
    /*if (selectedBrand) {
        assert takePicture != null;
        takePicture.setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorAccent));
        findViewById(R.id.control).setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimary));
    } else {
        assert takePicture != null;
        takePicture.setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorAccent2));
        findViewById(R.id.control).setBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimary2));
    }*/
    findViewById(R.id.scale_up_btn).setOnClickListener(mOnClickListener);
    findViewById(R.id.scale_down_btn).setOnClickListener(mOnClickListener);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayShowTitleEnabled(false);
    }

    if (savedInstanceState == null) {
        Bundle extras = getIntent().getExtras();
        if(extras != null) {
            itemID = extras.getString("id", null);
        }
    } else {
        itemID = (String) savedInstanceState.getSerializable("id");
    }

    if( itemID != null ) {
        new AsyncImageLoader().execute(itemID);

    } else {
        this.finish();
        return;
    }

    ViewTreeObserver viewTreeObserver = mCameraView.getViewTreeObserver();
    if (viewTreeObserver.isAlive()) {
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                /*if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                    mCameraView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                } else {
                    mCameraView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }*/
                cameraWidth = dp2px(mCameraView.getWidth());
                cameraHeight = dp2px(mCameraView.getHeight());

                Log.e("camB4Action", "" + cameraWidth + ", " + cameraHeight);
            }
        });
    }


}

@Override
protected void onResume() {
    super.onResume();
    mCameraView.start();
}

@Override
protected void onPause() {
    mCameraView.stop();
    super.onPause();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mBackgroundHandler != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            mBackgroundHandler.getLooper().quitSafely();
        } else {
            mBackgroundHandler.getLooper().quit();
        }
        mBackgroundHandler = null;
    }
}

private Drawable getFlippedDrawable(final Drawable d) {
    final Drawable[] arD = { d };
    return new LayerDrawable(arD) {
        @Override
        public void draw(final Canvas canvas) {
            canvas.save();
            canvas.scale(-1, 1, d.getBounds().width() / 2, d.getBounds().height() / 2);
            super.draw(canvas);
            canvas.restore();
        }
    };
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.camera, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.switch_flash:
            if (mCameraView != null) {
                mCurrentFlash = (mCurrentFlash + 1) % FLASH_OPTIONS.length;
                item.setTitle(FLASH_TITLES[mCurrentFlash]);
                item.setIcon(FLASH_ICONS[mCurrentFlash]);
                mCameraView.setFlash(FLASH_OPTIONS[mCurrentFlash]);
            }
            break;
        case R.id.switch_camera:
            if (mCameraView != null) {
                int facing = mCameraView.getFacing();
                mCameraView.setFacing(facing == CameraView.FACING_FRONT ?
                        CameraView.FACING_BACK : CameraView.FACING_FRONT);
            }
            break;
        case R.id.mirror_image:
            if (mCameraView != null) {
                SizeAwareImageView imageView = (SizeAwareImageView) mCameraView.findViewById(R.id.mImageView);
                imageView.setImageDrawable(getFlippedDrawable(imageView.getDrawable()));
                imageView.requestLayout();
            }
            break;
        case R.id.rotate_image:
            if (mCameraView != null) {
                rotateImage();
            }
            break;
    }
    return false;
}

  private Handler getBackgroundHandler() {
    if (mBackgroundHandler == null) {
        HandlerThread thread = new HandlerThread("background");
        thread.setPriority(Thread.MAX_PRIORITY);
        thread.start();
        mBackgroundHandler = new Handler(thread.getLooper());
    }
    return mBackgroundHandler;
}

public static Bitmap scaleBitmap(Bitmap bitmap, int wantedWidth, int wantedHeight, float rotation) {
    Log.e(TAG, "scaleBitmap: bitmapWidth: " + bitmap.getWidth() + ", bitmapHeight: " + bitmap.getHeight() );
    Log.e(TAG, "scaleBitmap: wantedWidth: " +
            ((rotation % 180 == 90) ? wantedHeight : wantedWidth) +
            ", wantedHeight: " + ((rotation % 180 == 90) ? wantedWidth : wantedHeight) );
    Bitmap output = Bitmap.createBitmap(
            (rotation % 180 == 90) ? wantedHeight : wantedWidth,
            (rotation % 180 == 90) ? wantedWidth : wantedHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(output);
    Matrix m = new Matrix();
    m.setScale((float)
            ((rotation % 180 == 90) ? wantedHeight : wantedWidth) / bitmap.getWidth(),
            (float) ((rotation % 180 == 90) ? wantedWidth : wantedHeight) / bitmap.getHeight());

    canvas.drawBitmap(bitmap, m, new Paint());
    return output;
    /*Matrix m = new Matrix();

    m.setRectToRect(new RectF(0, 0, b.getWidth(), b.getHeight()),
            new RectF(0, 0, (rotation % 180 == 90) ? wantedHeight : wantedWidth,
                    (rotation % 180 == 90) ? wantedWidth : wantedHeight), Matrix.ScaleToFit.CENTER);
    return Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);*/
}

private CameraView.Callback mCallback
        = new CameraView.Callback() {
    ProgressiveToast progressiveToast;

    @Override
    public void onCameraOpened(CameraView cameraView) {
        Log.d(TAG, "onCameraOpened");
    }

    @Override
    public void onCameraClosed(CameraView cameraView) {
        Log.d(TAG, "onCameraClosed");
    }

    @Override
    public void onPictureTaken(CameraView cameraView, final byte[] data) {
        Log.d(TAG, "onPictureTaken " + data.length);
        /*TastyToast.makeText(cameraView.getContext(), getString(R.string.pic_being_saved),
                TastyToast.LENGTH_LONG, TastyToast.INFO);*/
        progressiveToast = ProgressiveToast.getInstance();
        progressiveToast.show(CaptureActivity.this, getString(R.string.in_action_be_patient), -1);
        getBackgroundHandler().post(new Runnable() {
            @Override
            public void run() {
                mCameraView.stop();
                // This demo app saves the taken picture to a constant file.
                // $ adb pull /sdcard/Android/data/com.google.android.cameraview.demo/files/Pictures/picture.jpg
                SizeAwareImageView imageView = ((SizeAwareImageView) mCameraView.findViewById(R.id.mImageView));
                Bitmap imageBitmap =
                        drawableToBitmap(imageView.getDrawable());
                Matrix matrix = new Matrix();
                float rotation = mCameraView.findViewById(R.id.mImageView).getRotation();
                matrix.postRotate(rotation);
                //matrix.postScale(drawableWidth, drawableHeight);

/*
                    matrix.setScale((float)
                            ((rotation% 180 == 90) ? drawableWidth : drawableHeight) / imageBitmap.getWidth(),
                            (float) ((rotation% 180 == 90) ? drawableWidth : drawableHeight) / imageBitmap.getHeight());*/
                    Log.e(TAG, "rotation: " + rotation);

                imageBitmap = Bitmap.createBitmap(imageBitmap , 0, 0,
                        imageBitmap.getWidth(), imageBitmap.getHeight(), matrix, true);
                imageBitmap = scaleBitmap(imageBitmap, drawableWidth, drawableHeight, rotation);


                Bitmap cameraBmp = BitmapFactory.decodeByteArray(data, 0, data.length);
                cameraBmp = fixOrientation(cameraBmp);
                File dir = new File (Environment.getExternalStorageDirectory().getAbsolutePath()
                        + File.separator + getString(R.string.gallery_folder_name) +
                        (selectedBrand ? getString(R.string.ibr_eng) :
                        getString(R.string.tiyaco_eng)));
                dir.mkdirs();
                File file = new File(dir.getAbsolutePath() ,
                        Long.toString(Calendar.getInstance().getTimeInMillis()) + ".jpg");
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                OutputStream os = null;
                InputStream is = overlayBitmapToCenter(cameraBmp, imageBitmap, rotation);
                byte[] buffer = new byte[10 * 1024];
                int n = 0;
                try {
                    os = new FileOutputStream(file);
                    while (-1 != (n = is.read(buffer))) {
                        os.write(buffer, 0, n);
                    }
                } catch (IOException e) {
                    Log.w(TAG, "Cannot write to " + file, e);
                } finally {
                    if (os != null) {
                        try {
                            os.close();
                        } catch (IOException e) {
                            // Ignore
                        }
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (mCameraView != null)
                                    try {
                                        mCameraView.start();
                                    } catch (Exception ignored){}
                                if (takePicture != null) {
                                    takePicture.setEnabled(true);
                                }
                                progressiveToast.dismiss();
                                TastyToast.makeText(getApplicationContext(), getString(R.string.picture_taken),
                                        TastyToast.LENGTH_LONG, TastyToast.SUCCESS);
                            }
                        });
                    }
                }
            }
        });
    }

};


public Bitmap fixOrientation(Bitmap mBitmap) {
    if (mBitmap.getWidth() > mBitmap.getHeight()) {
        Matrix matrix = new Matrix();
        matrix.postRotate(90);
        return Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
    }
    return mBitmap;
}

private int dp2px(int dp) {
    return (int)((dp * getResources().getDisplayMetrics().density) + 0.5);
}

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



public ByteArrayInputStream overlayBitmapToCenter(Bitmap bitmap1, Bitmap bitmap2, float rotation) {
    float alpha = (float)cameraWidth / (float)((rotation % 180 == 90) ? drawableHeight : drawableWidth);
    float beta = (float)((rotation % 180 == 90) ? drawableHeight : drawableWidth) /
            (float)((rotation % 180 == 90) ? drawableWidth : drawableHeight);
    int bitmap1Width = bitmap1.getWidth();
    int bitmap1Height = bitmap1.getHeight();

    Bitmap scaledImg = Bitmap.createScaledBitmap(bitmap2, (int)((float)bitmap1Width / alpha),
            (int)(((float)bitmap1Width / alpha) / beta), false);


    int bitmap2Width = scaledImg.getWidth();
    int bitmap2Height = scaledImg.getHeight();

    /*Log.e("cam", "" + bitmap1Width + ", " + bitmap1Height );
    Log.e("img", "" + bitmap2Width + ", " + bitmap2Height );
    Log.e("alpha", "" + alpha );
    Log.e("beta", "" + beta );*/

    float marginLeft = (float) (bitmap1Width * 0.5 - bitmap2Width * 0.5);
    float marginTop = (float) (bitmap1Height * 0.5 - bitmap2Height * 0.5);

    Bitmap overlayBitmap = Bitmap.createBitmap(bitmap1Width, bitmap1Height, bitmap1.getConfig());
    Canvas canvas = new Canvas(overlayBitmap);
    canvas.drawBitmap(bitmap1, new Matrix(), null);
    canvas.drawBitmap(scaledImg, marginLeft, marginTop, null);

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    overlayBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
    return new ByteArrayInputStream(stream.toByteArray());
}




private class AsyncImageLoader extends AsyncTask<String, Void, BitmapDrawable>{
    private Realm realm;

    private ProductModel product;

    @Override
    protected BitmapDrawable doInBackground(String... itemIds) {
        realm = Realm.getDefaultInstance();
        product = realm.where(ProductModel.class)
                .equalTo("isIbr", selectedBrand)
                .equalTo("id", itemIds[0])
                .findFirst();
        byte[] image = product.getImage();
        product = null;
        realm.close();
        BitmapDrawable mDrawable = new BitmapDrawable(getResources(), BitmapFactory
                .decodeByteArray(image, 0, image.length));
        int mDrawableHeight = mDrawable.getIntrinsicHeight();
        int mDrawableWidth = mDrawable.getIntrinsicWidth();
        int valueInPixels = (int) getResources().getDimension(R.dimen.video_view_dimen);
        mDrawable.setBounds(0, 0, valueInPixels, valueInPixels * mDrawableHeight / mDrawableWidth);
        return mDrawable;
    }

    @Override
    protected void onPostExecute(BitmapDrawable drawable) {
        super.onPostExecute(drawable);

        LayoutInflater vi = (LayoutInflater) getApplicationContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        final View v = vi.inflate(R.layout.imageview_product, null);
        ((SizeAwareImageView)v).setImageDrawable(drawable);



        ViewTreeObserver viewTreeObserver = v.getViewTreeObserver();
        if (viewTreeObserver.isAlive()) {
            viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    Log.e(TAG, "onGlobalLayout: updating sizes for drawable");
                    float[] sizez = ((SizeAwareImageView) v).getImageWidthAndHeight();
                    /*if (v.getRotation() == 90 || v.getRotation() == 270) {
                        drawableWidth = dp2px(sizez[1]);
                        drawableHeight = dp2px(sizez[0]);
                    } else {
                        drawableWidth = dp2px(sizez[0]);
                        drawableHeight = dp2px(sizez[1]);
                    }*/
                    drawableWidth = dp2px((int) sizez[0]);
                    drawableHeight = dp2px((int) sizez[1]);

                    /*Log.e("picB4Action", "" + drawableWidth + ", " + drawableHeight);*/
                }
            });
        }
        int px = (int) (getResources().getDimension(R.dimen.video_view_dimen)/* /
                getResources().getDisplayMetrics().density*/);

        mCameraView.addView(v, new FrameLayout.LayoutParams(px, px, Gravity.CENTER));

    }
}
}

SizeAwareImageView.java :

public class SizeAwareImageView extends ImageView {
    public SizeAwareImageView(Context context) {
        super(context);
    }

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

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

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    // Get image matrix values and place them in an array
    float[] f = new float[9];
    getImageMatrix().getValues(f);

    // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
    final float scaleX = f[Matrix.MSCALE_X];
    final float scaleY = f[Matrix.MSCALE_Y];

    // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
    final Drawable d = getDrawable();
    final int origW = d.getIntrinsicWidth();
    final int origH = d.getIntrinsicHeight();

    // Calculate the actual dimensions
    final int actW = Math.round(origW * scaleX);
    final int actH = Math.round(origH * scaleY);

    Log.e("DBG", "["+origW+","+origH+"] -> ["+actW+","+actH+"] & scales: x="+scaleX+" y="+scaleY);
}

public float[] getMatrixValues() {
    float[] f = new float[9];
    getImageMatrix().getValues(f);
    return f;

}

public float[] getImageWidthAndHeight() {
    // Get image matrix values and place them in an array
    float[] f = new float[9];
    getImageMatrix().getValues(f);

    // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
    final float scaleX = f[Matrix.MSCALE_X];
    final float scaleY = f[Matrix.MSCALE_Y];

    // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
    final Drawable d = getDrawable();
    final int origW = d.getIntrinsicWidth();
    final int origH = d.getIntrinsicHeight();

    // Calculate the actual dimensions
    final int actW = Math.round(origW * scaleX);
    final int actH = Math.round(origH * scaleY);
    //Log.e("DBG", "["+origW+","+origH+"] -> ["+actW+","+actH+"] & scales: x="+scaleX+" y="+scaleY);
    return new float[] {actW, actH, scaleX, scaleY};
}

}
like image 61
M. Erfan Mowlaei Avatar answered Oct 21 '22 09:10

M. Erfan Mowlaei