Example usage for android.graphics Canvas save

List of usage examples for android.graphics Canvas save

Introduction

In this page you can find the example usage for android.graphics Canvas save.

Prototype

public int save() 

Source Link

Document

Saves the current matrix and clip onto a private stack.

Usage

From source file:com.mappn.gfan.ui.HomeTabActivity.java

private Bitmap drawBitmap(DisplayMetrics dm, Bitmap background, Bitmap corner) {
    Canvas canvas = new Canvas();
    final int height = background.getScaledHeight(dm);
    final int width = background.getScaledWidth(dm);
    Bitmap smallBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    canvas.setBitmap(smallBitmap);//  w ww  . jav a  2  s . c  o m
    Paint textPainter = new Paint(Paint.ANTI_ALIAS_FLAG);
    canvas.drawBitmap(background, 0, 0, textPainter);
    textPainter.setXfermode(new PorterDuffXfermode(Mode.SRC_OVER));
    canvas.drawBitmap(corner, width - corner.getScaledWidth(dm), 0, textPainter);
    canvas.save();
    return smallBitmap;
}

From source file:com.ferdi2005.secondgram.AndroidUtilities.java

private static Intent createShortcutIntent(long did, boolean forDelete) {
    Intent shortcutIntent = new Intent(ApplicationLoader.applicationContext, OpenChatReceiver.class);

    int lower_id = (int) did;
    int high_id = (int) (did >> 32);

    TLRPC.User user = null;/*from w  w w . jav  a 2 s. c  om*/
    TLRPC.Chat chat = null;
    if (lower_id == 0) {
        shortcutIntent.putExtra("encId", high_id);
        TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(high_id);
        if (encryptedChat == null) {
            return null;
        }
        user = MessagesController.getInstance().getUser(encryptedChat.user_id);
    } else if (lower_id > 0) {
        shortcutIntent.putExtra("userId", lower_id);
        user = MessagesController.getInstance().getUser(lower_id);
    } else if (lower_id < 0) {
        chat = MessagesController.getInstance().getChat(-lower_id);
        shortcutIntent.putExtra("chatId", -lower_id);
    } else {
        return null;
    }
    if (user == null && chat == null) {
        return null;
    }

    String name;
    TLRPC.FileLocation photo = null;

    if (user != null) {
        name = ContactsController.formatName(user.first_name, user.last_name);
        if (user.photo != null) {
            photo = user.photo.photo_small;
        }
    } else {
        name = chat.title;
        if (chat.photo != null) {
            photo = chat.photo.photo_small;
        }
    }

    shortcutIntent.setAction("com.tmessages.openchat" + did);
    shortcutIntent.addFlags(0x4000000);

    Intent addIntent = new Intent();
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
    addIntent.putExtra("duplicate", false);
    if (!forDelete) {
        Bitmap bitmap = null;
        if (photo != null) {
            try {
                File path = FileLoader.getPathToAttach(photo, true);
                bitmap = BitmapFactory.decodeFile(path.toString());
                if (bitmap != null) {
                    int size = AndroidUtilities.dp(58);
                    Bitmap result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
                    result.eraseColor(Color.TRANSPARENT);
                    Canvas canvas = new Canvas(result);
                    BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,
                            Shader.TileMode.CLAMP);
                    if (roundPaint == null) {
                        roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
                        bitmapRect = new RectF();
                    }
                    float scale = size / (float) bitmap.getWidth();
                    canvas.save();
                    canvas.scale(scale, scale);
                    roundPaint.setShader(shader);
                    bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
                    canvas.drawRoundRect(bitmapRect, bitmap.getWidth(), bitmap.getHeight(), roundPaint);
                    canvas.restore();
                    Drawable drawable = ApplicationLoader.applicationContext.getResources()
                            .getDrawable(R.drawable.book_logo);
                    int w = AndroidUtilities.dp(15);
                    int left = size - w - AndroidUtilities.dp(2);
                    int top = size - w - AndroidUtilities.dp(2);
                    drawable.setBounds(left, top, left + w, top + w);
                    drawable.draw(canvas);
                    try {
                        canvas.setBitmap(null);
                    } catch (Exception e) {
                        //don't promt, this will crash on 2.x
                    }
                    bitmap = result;
                }
            } catch (Throwable e) {
                FileLog.e(e);
            }
        }
        if (bitmap != null) {
            addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
        } else {
            if (user != null) {
                if (user.bot) {
                    addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource
                            .fromContext(ApplicationLoader.applicationContext, R.drawable.book_bot));
                } else {
                    addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource
                            .fromContext(ApplicationLoader.applicationContext, R.drawable.book_user));
                }
            } else if (chat != null) {
                if (ChatObject.isChannel(chat) && !chat.megagroup) {
                    addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource
                            .fromContext(ApplicationLoader.applicationContext, R.drawable.book_channel));
                } else {
                    addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource
                            .fromContext(ApplicationLoader.applicationContext, R.drawable.book_group));
                }
            }
        }
    }
    return addIntent;
}

From source file:com.example.view.wheel.WheelView.java

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (itemsLayout == null) {
        if (itemsWidth == 0) {
            calculateLayoutWidth(getWidth(), MeasureSpec.EXACTLY);
        } else {/*  w  w  w .  j av a 2s . c  om*/
            createLayouts(itemsWidth, labelWidth);
        }
    }

    if (itemsWidth > 0) {
        canvas.save();
        // Skip padding space and hide a part of top and bottom items
        canvas.translate(PADDING, -ITEM_OFFSET);
        drawItems(canvas);
        drawValue(canvas);
        canvas.restore();
    }

    drawCenterRect(canvas);
    //   drawShadows(canvas);
}

From source file:devlight.io.library.ArcProgressStackView.java

@Override
protected void onDraw(final Canvas canvas) {
    super.onDraw(canvas);

    // Save and rotate to start angle
    canvas.save();
    final float radius = mSize * 0.5F;
    canvas.rotate(mStartAngle, radius, radius);

    // Draw all of progress
    for (int i = 0; i < mModels.size(); i++) {
        final Model model = mModels.get(i);
        // Get progress for current model
        float progressFraction = mIsAnimated && !isInEditMode()
                ? (model.mLastProgress + (mAnimatedFraction * (model.getProgress() - model.mLastProgress)))
                        / MAX_PROGRESS/*from w  w w .  ja va 2  s  . c  o  m*/
                : model.getProgress() / MAX_PROGRESS;
        if (i != mActionMoveModelIndex && mActionMoveModelIndex != ANIMATE_ALL_INDEX)
            progressFraction = model.getProgress() / MAX_PROGRESS;
        final float progress = progressFraction * mSweepAngle;

        // Check if model have gradient
        final boolean isGradient = model.getColors() != null;
        // Set width of progress
        mProgressPaint.setStrokeWidth(mProgressModelSize);

        // Set model arc progress
        model.mPath.reset();
        model.mPath.addArc(model.mBounds, 0.0F, progress);

        // Draw gradient progress or solid
        resetShadowLayer();
        mProgressPaint.setShader(null);
        mProgressPaint.setStyle(Paint.Style.STROKE);

        if (mIsModelBgEnabled) {
            //noinspection ResourceAsColor
            mProgressPaint.setColor(isInEditMode() ? mPreviewModelBgColor : model.getBgColor());
            canvas.drawArc(model.mBounds, 0.0F, mSweepAngle, false, mProgressPaint);
            if (!isInEditMode())
                mProgressPaint.clearShadowLayer();
        }

        // Check if gradient for draw shadow at first and then gradient progress
        if (isGradient) {
            if (!mIsModelBgEnabled) {
                canvas.drawPath(model.mPath, mProgressPaint);

                if (!isInEditMode())
                    mProgressPaint.clearShadowLayer();
            }

            mProgressPaint.setShader(model.mSweepGradient);
        } else
            mProgressPaint.setColor(model.getColor());

        // Here we draw main progress
        mProgressPaint.setAlpha(255);
        canvas.drawPath(model.mPath, mProgressPaint);

        // Preview mode
        if (isInEditMode())
            continue;

        // Get model title bounds
        mTextPaint.setTextSize(mProgressModelSize * 0.5F);
        mTextPaint.getTextBounds(model.getTitle(), 0, model.getTitle().length(), model.mTextBounds);

        // Draw title at start with offset
        final float titleHorizontalOffset = model.mTextBounds.height() * 0.5F;
        final float progressLength = (float) (Math.PI / 180.0F) * progress * model.mBounds.width() * 0.5F;
        final String title = (String) TextUtils.ellipsize(model.getTitle(), mTextPaint,
                progressLength - titleHorizontalOffset * 2, TextUtils.TruncateAt.END);
        canvas.drawTextOnPath(title, model.mPath, mIsRounded ? 0.0F : titleHorizontalOffset,
                titleHorizontalOffset, mTextPaint);

        // Get pos and tan at final path point
        model.mPathMeasure.setPath(model.mPath, false);
        model.mPathMeasure.getPosTan(model.mPathMeasure.getLength(), model.mPos, model.mTan);

        // Get title width
        final float titleWidth = model.mTextBounds.width();

        // Create model progress like : 23%
        final String percentProgress = String.format("%d%%", (int) model.getProgress());
        // Get progress text bounds
        mTextPaint.setTextSize(mProgressModelSize * 0.35f);
        mTextPaint.getTextBounds(percentProgress, 0, percentProgress.length(), model.mTextBounds);

        // Get pos tan with end point offset and check whether the rounded corners for offset
        final float progressHorizontalOffset = mIndicatorOrientation == IndicatorOrientation.VERTICAL
                ? model.mTextBounds.height() * 0.5F
                : model.mTextBounds.width() * 0.5F;
        final float indicatorProgressOffset = (mIsRounded ? progressFraction : 1.0F)
                * (-progressHorizontalOffset - titleHorizontalOffset
                        - (mIsRounded ? model.mTextBounds.height() * 2.0F : 0.0F));
        model.mPathMeasure.getPosTan(model.mPathMeasure.getLength() + indicatorProgressOffset, model.mPos,
                mIndicatorOrientation == IndicatorOrientation.VERTICAL && !mIsRounded ? new float[2]
                        : model.mTan);

        // Check if there available place for indicator
        if ((titleWidth + model.mTextBounds.height() + titleHorizontalOffset * 2.0F)
                - indicatorProgressOffset < progressLength) {
            // Get rotate indicator progress angle for progress value
            float indicatorProgressAngle = (float) (Math.atan2(model.mTan[1], model.mTan[0])
                    * (180.0F / Math.PI));
            // Get arc angle of progress indicator
            final float indicatorLengthProgressAngle = ((progressLength + indicatorProgressOffset)
                    / (model.mBounds.width() * 0.5F)) * (float) (180.0F / Math.PI);

            // Detect progress indicator position : left or right and then rotate
            if (mIndicatorOrientation == IndicatorOrientation.VERTICAL) {
                // Get X point of arc angle progress indicator
                final float x = (float) (model.mBounds.width() * 0.5F
                        * (Math.cos((indicatorLengthProgressAngle + mStartAngle) * Math.PI / 180.0F)))
                        + model.mBounds.centerX();
                indicatorProgressAngle += (x > radius) ? -90.0F : 90.0F;
            } else {
                // Get Y point of arc angle progress indicator
                final float y = (float) (model.mBounds.height() * 0.5F
                        * (Math.sin((indicatorLengthProgressAngle + mStartAngle) * Math.PI / 180.0F)))
                        + model.mBounds.centerY();
                indicatorProgressAngle += (y > radius) ? 180.0F : 0.0F;
            }

            // Draw progress value
            canvas.save();
            canvas.rotate(indicatorProgressAngle, model.mPos[0], model.mPos[1]);
            canvas.drawText(percentProgress, model.mPos[0] - model.mTextBounds.exactCenterX(),
                    model.mPos[1] - model.mTextBounds.exactCenterY(), mTextPaint);
            canvas.restore();
        }

        // Check if gradient and have rounded corners, because we must to create elevation effect
        // for start progress corner
        if ((isGradient || mIsLeveled) && mIsRounded && progress != 0) {
            model.mPathMeasure.getPosTan(0.0F, model.mPos, model.mTan);

            // Set paint for overlay rounded gradient with shadow
            setLevelShadowLayer();
            //noinspection ResourceAsColor
            mLevelPaint.setColor(isGradient ? model.getColors()[0] : model.getColor());

            // Get bounds of start pump
            final float halfSize = mProgressModelSize * 0.5F;
            final RectF arcRect = new RectF(model.mPos[0] - halfSize, model.mPos[1] - halfSize,
                    model.mPos[0] + halfSize, model.mPos[1] + halfSize + 2.0F);
            canvas.drawArc(arcRect, 0.0F, -180.0F, true, mLevelPaint);
        }
    }

    // Restore after drawing
    canvas.restore();
}

From source file:com.dongdong.wheel.WheelView.java

/**
 * Draws value and mLabel layout/*from w  w w.  j a  v  a  2s .  c o m*/
 *
 * @param canvas the canvas for drawing
 */
private void drawValue(Canvas canvas) {
    mValuePaint.setColor(VALUE_TEXT_COLOR);
    mValuePaint.drawableState = getDrawableState();

    Rect bounds = new Rect();
    mItemsLayout.getLineBounds(mVisibleItems / 2, bounds);

    // draw mLabel
    if (mLabelLayout != null) {
        canvas.save();
        canvas.translate(mItemsLayout.getWidth() + LABEL_OFFSET, bounds.top);
        mLabelLayout.draw(canvas);
        canvas.restore();
    }

    // draw current value
    if (mValueLayout != null) {
        canvas.save();
        canvas.translate(0, bounds.top + mScrollingOffset);
        mValueLayout.draw(canvas);
        canvas.restore();
    }
}

From source file:com.scvngr.levelup.core.ui.view.LevelUpCodeView.java

/**
 * Draws the QR code to the canvas, scaling it up to fit the measured size of the view. If
 * enabled, this also draws the colored target areas per
 * {@link #drawColoredTargetAreas(Canvas, LevelUpQrCodeImage)}.
 *
 * @param canvas the drawing canvas.//w w  w .java  2  s .com
 * @param levelUpQrCodeImage the image of the QR code with target marker information.
 */
private void drawQrCode(@NonNull final Canvas canvas, @NonNull final LevelUpQrCodeImage levelUpQrCodeImage) {
    final Bitmap codeBitmap = levelUpQrCodeImage.getBitmap();
    /*
     * The code is cached in the smallest size and must be scaled before being displayed. It is
     * necessary to draw it directly onto a canvas and scale it in the same operation for
     * efficiency (so we do not have any perceivable lag when switching tip values).
     */
    mCodeScalingMatrix.setScale((float) getMeasuredWidth() / codeBitmap.getWidth(),
            (float) getMeasuredHeight() / codeBitmap.getHeight());

    // Save the canvas without the scaling matrix.
    canvas.save();

    canvas.concat(mCodeScalingMatrix);
    canvas.drawBitmap(codeBitmap, 0, 0, mQrCodePaint);

    if (mIsColorizeSet) {
        drawColoredTargetAreas(canvas, levelUpQrCodeImage);
    }

    canvas.restore();
}

From source file:cn.androidy.androiddevelopmentpatterns.interactivechart.InteractiveLineGraphView.java

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // Draws axes and text labels
    drawAxes(canvas);//from w ww .j av  a  2s .co  m

    // Clips the next few drawing operations to the content area
    int clipRestoreCount = canvas.save();
    canvas.clipRect(mContentRect);

    drawDataSeriesUnclipped(canvas);
    drawEdgeEffectsUnclipped(canvas);

    // Removes clipping rectangle
    canvas.restoreToCount(clipRestoreCount);

    // Draws chart container
    canvas.drawRect(mContentRect, mAxisPaint);
}

From source file:com.dongdong.wheel.WheelView.java

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (mItemsLayout == null) {
        if (mItemsWidth == 0) {
            calculateLayoutWidth(getWidth(), MeasureSpec.EXACTLY);
        } else {/*from  ww w . j ava2  s.com*/
            createLayouts(mItemsWidth, mLabelWidth);
        }
    }

    if (mItemsWidth > 0) {
        canvas.save();
        // Skip padding space and hide a part of top and bottom items
        canvas.translate(PADDING, -ITEM_OFFSET);
        drawItems(canvas);
        drawValue(canvas);
        canvas.restore();
    }

    drawCenterRect(canvas);
    drawShadows(canvas);
}

From source file:com.raibow.yamahaspk.filtershow.imageshow.ImageShow.java

public void drawImageAndAnimate(Canvas canvas, Bitmap image) {
    if (image == null) {
        return;/* w  w w.  j  a v  a 2s .co m*/
    }
    MasterImage master = MasterImage.getImage();
    Matrix m = master.computeImageToScreen(image, 0, false);
    if (m == null) {
        return;
    }

    canvas.save();

    RectF d = new RectF(0, 0, image.getWidth(), image.getHeight());
    m.mapRect(d);
    d.roundOut(mImageBounds);

    boolean showAnimatedImage = master.onGoingNewLookAnimation();
    if (!showAnimatedImage && mDidStartAnimation) {
        // animation ended, but do we have the correct image to show?
        if (master.getPreset().equals(master.getCurrentPreset())) {
            // we do, let's stop showing the animated image
            mDidStartAnimation = false;
            MasterImage.getImage().resetAnimBitmap();
        } else {
            showAnimatedImage = true;
        }
    } else if (showAnimatedImage) {
        mDidStartAnimation = true;
    }

    if (showAnimatedImage) {
        canvas.save();

        // Animation uses the image before the change
        Bitmap previousImage = master.getPreviousImage();
        Matrix mp = master.computeImageToScreen(previousImage, 0, false);
        RectF dp = new RectF(0, 0, previousImage.getWidth(), previousImage.getHeight());
        mp.mapRect(dp);
        Rect previousBounds = new Rect();
        dp.roundOut(previousBounds);
        float centerX = dp.centerX();
        float centerY = dp.centerY();
        boolean needsToDrawImage = true;

        if (master.getCurrentLookAnimation() == MasterImage.CIRCLE_ANIMATION) {
            float maskScale = MasterImage.getImage().getMaskScale();
            if (maskScale >= 0.0f) {
                float maskW = sMask.getWidth() / 2.0f;
                float maskH = sMask.getHeight() / 2.0f;
                Point point = mActivity.hintTouchPoint(this);
                float maxMaskScale = 2 * Math.max(getWidth(), getHeight()) / Math.min(maskW, maskH);
                maskScale = maskScale * maxMaskScale;
                float x = point.x - maskW * maskScale;
                float y = point.y - maskH * maskScale;

                // Prepare the shader
                mShaderMatrix.reset();
                mShaderMatrix.setScale(1.0f / maskScale, 1.0f / maskScale);
                mShaderMatrix.preTranslate(-x + mImageBounds.left, -y + mImageBounds.top);
                float scaleImageX = mImageBounds.width() / (float) image.getWidth();
                float scaleImageY = mImageBounds.height() / (float) image.getHeight();
                mShaderMatrix.preScale(scaleImageX, scaleImageY);
                mMaskPaint.reset();
                mMaskPaint.setShader(createShader(image));
                mMaskPaint.getShader().setLocalMatrix(mShaderMatrix);

                drawShadow(canvas, mImageBounds); // as needed
                canvas.drawBitmap(previousImage, m, mPaint);
                canvas.clipRect(mImageBounds);
                canvas.translate(x, y);
                canvas.scale(maskScale, maskScale);
                canvas.drawBitmap(sMask, 0, 0, mMaskPaint);
                needsToDrawImage = false;
            }
        } else if (master.getCurrentLookAnimation() == MasterImage.ROTATE_ANIMATION) {
            Rect d1 = computeImageBounds(master.getPreviousImage().getHeight(),
                    master.getPreviousImage().getWidth());
            Rect d2 = computeImageBounds(master.getPreviousImage().getWidth(),
                    master.getPreviousImage().getHeight());
            float finalScale = d1.width() / (float) d2.height();
            finalScale = (1.0f * (1.0f - master.getAnimFraction())) + (finalScale * master.getAnimFraction());
            canvas.rotate(master.getAnimRotationValue(), centerX, centerY);
            canvas.scale(finalScale, finalScale, centerX, centerY);
        } else if (master.getCurrentLookAnimation() == MasterImage.MIRROR_ANIMATION) {
            if (master.getCurrentFilterRepresentation() instanceof FilterMirrorRepresentation) {
                FilterMirrorRepresentation rep = (FilterMirrorRepresentation) master
                        .getCurrentFilterRepresentation();

                ImagePreset preset = master.getPreset();
                ArrayList<FilterRepresentation> geometry = (ArrayList<FilterRepresentation>) preset
                        .getGeometryFilters();
                GeometryMathUtils.GeometryHolder holder = null;
                holder = GeometryMathUtils.unpackGeometry(geometry);

                if (holder.rotation.value() == 90 || holder.rotation.value() == 270) {
                    if (rep.isHorizontal() && !rep.isVertical()) {
                        canvas.scale(1, master.getAnimRotationValue(), centerX, centerY);
                    } else if (rep.isVertical() && !rep.isHorizontal()) {
                        canvas.scale(1, master.getAnimRotationValue(), centerX, centerY);
                    } else if (rep.isHorizontal() && rep.isVertical()) {
                        canvas.scale(master.getAnimRotationValue(), 1, centerX, centerY);
                    } else {
                        canvas.scale(master.getAnimRotationValue(), 1, centerX, centerY);
                    }
                } else {
                    if (rep.isHorizontal() && !rep.isVertical()) {
                        canvas.scale(master.getAnimRotationValue(), 1, centerX, centerY);
                    } else if (rep.isVertical() && !rep.isHorizontal()) {
                        canvas.scale(master.getAnimRotationValue(), 1, centerX, centerY);
                    } else if (rep.isHorizontal() && rep.isVertical()) {
                        canvas.scale(1, master.getAnimRotationValue(), centerX, centerY);
                    } else {
                        canvas.scale(1, master.getAnimRotationValue(), centerX, centerY);
                    }
                }
            }
        }

        if (needsToDrawImage) {
            drawShadow(canvas, previousBounds); // as needed
            canvas.drawBitmap(previousImage, mp, mPaint);
        }

        canvas.restore();
    } else {
        drawShadow(canvas, mImageBounds); // as needed
        canvas.drawBitmap(image, m, mPaint);
    }

    canvas.restore();
}

From source file:com.android.gallery3d.filtershow.imageshow.ImageShow.java

public void drawImageAndAnimate(Canvas canvas, Bitmap image) {
    if (image == null) {
        return;/*  w w w .j a v a  2 s. c  om*/
    }
    MasterImage master = MasterImage.getImage();
    Matrix m = master.computeImageToScreen(image, 0, false);
    if (m == null) {
        return;
    }

    canvas.save();

    RectF d = new RectF(0, 0, image.getWidth(), image.getHeight());
    m.mapRect(d);
    d.roundOut(mImageBounds);

    boolean showAnimatedImage = master.onGoingNewLookAnimation();
    if (!showAnimatedImage && mDidStartAnimation) {
        // animation ended, but do we have the correct image to show?
        if (master.getPreset().equals(master.getCurrentPreset())) {
            // we do, let's stop showing the animated image
            mDidStartAnimation = false;
            MasterImage.getImage().resetAnimBitmap();
        } else {
            showAnimatedImage = true;
        }
    } else if (showAnimatedImage) {
        mDidStartAnimation = true;
    }

    if (showAnimatedImage) {
        canvas.save();

        // Animation uses the image before the change
        Bitmap previousImage = master.getPreviousImage();
        Matrix mp = master.computeImageToScreen(previousImage, 0, false);
        RectF dp = new RectF(0, 0, previousImage.getWidth(), previousImage.getHeight());
        mp.mapRect(dp);
        Rect previousBounds = new Rect();
        dp.roundOut(previousBounds);
        float centerX = dp.centerX();
        float centerY = dp.centerY();
        boolean needsToDrawImage = true;

        if (master.getCurrentLookAnimation() == MasterImage.CIRCLE_ANIMATION) {
            float maskScale = MasterImage.getImage().getMaskScale();
            if (maskScale >= 0.0f) {
                float maskW = sMask.getWidth() / 2.0f;
                float maskH = sMask.getHeight() / 2.0f;
                Point point = mActivity.hintTouchPoint(this);
                float maxMaskScale = 2 * Math.max(getWidth(), getHeight()) / Math.min(maskW, maskH);
                maskScale = maskScale * maxMaskScale;
                float x = point.x - maskW * maskScale;
                float y = point.y - maskH * maskScale;

                // Prepare the shader
                mShaderMatrix.reset();
                mShaderMatrix.setScale(1.0f / maskScale, 1.0f / maskScale);
                mShaderMatrix.preTranslate(-x + mImageBounds.left, -y + mImageBounds.top);
                float scaleImageX = mImageBounds.width() / (float) image.getWidth();
                float scaleImageY = mImageBounds.height() / (float) image.getHeight();
                mShaderMatrix.preScale(scaleImageX, scaleImageY);
                mMaskPaint.reset();
                Shader maskShader = createShader(image);
                maskShader.setLocalMatrix(mShaderMatrix);
                mMaskPaint.setShader(maskShader);

                drawShadow(canvas, mImageBounds); // as needed
                canvas.drawBitmap(previousImage, m, mPaint);
                canvas.clipRect(mImageBounds);
                canvas.translate(x, y);
                canvas.scale(maskScale, maskScale);
                canvas.drawBitmap(sMask, 0, 0, mMaskPaint);
                needsToDrawImage = false;
            }
        } else if (master.getCurrentLookAnimation() == MasterImage.ROTATE_ANIMATION) {
            Rect d1 = computeImageBounds(master.getPreviousImage().getHeight(),
                    master.getPreviousImage().getWidth());
            Rect d2 = computeImageBounds(master.getPreviousImage().getWidth(),
                    master.getPreviousImage().getHeight());
            float finalScale = d1.width() / (float) d2.height();
            finalScale = (1.0f * (1.0f - master.getAnimFraction())) + (finalScale * master.getAnimFraction());
            canvas.rotate(master.getAnimRotationValue(), centerX, centerY);
            canvas.scale(finalScale, finalScale, centerX, centerY);
        } else if (master.getCurrentLookAnimation() == MasterImage.MIRROR_ANIMATION) {
            if (master.getCurrentFilterRepresentation() instanceof FilterMirrorRepresentation) {
                FilterMirrorRepresentation rep = (FilterMirrorRepresentation) master
                        .getCurrentFilterRepresentation();

                ImagePreset preset = master.getPreset();
                ArrayList<FilterRepresentation> geometry = (ArrayList<FilterRepresentation>) preset
                        .getGeometryFilters();
                GeometryMathUtils.GeometryHolder holder = null;
                holder = GeometryMathUtils.unpackGeometry(geometry);

                if (holder.rotation.value() == 90 || holder.rotation.value() == 270) {
                    if (rep.isHorizontal() && !rep.isVertical()) {
                        canvas.scale(1, master.getAnimRotationValue(), centerX, centerY);
                    } else if (rep.isVertical() && !rep.isHorizontal()) {
                        canvas.scale(1, master.getAnimRotationValue(), centerX, centerY);
                    } else if (rep.isHorizontal() && rep.isVertical()) {
                        canvas.scale(master.getAnimRotationValue(), 1, centerX, centerY);
                    } else {
                        canvas.scale(master.getAnimRotationValue(), 1, centerX, centerY);
                    }
                } else {
                    if (rep.isHorizontal() && !rep.isVertical()) {
                        canvas.scale(master.getAnimRotationValue(), 1, centerX, centerY);
                    } else if (rep.isVertical() && !rep.isHorizontal()) {
                        canvas.scale(master.getAnimRotationValue(), 1, centerX, centerY);
                    } else if (rep.isHorizontal() && rep.isVertical()) {
                        canvas.scale(1, master.getAnimRotationValue(), centerX, centerY);
                    } else {
                        canvas.scale(1, master.getAnimRotationValue(), centerX, centerY);
                    }
                }
            }
        }

        if (needsToDrawImage) {
            drawShadow(canvas, previousBounds); // as needed
            canvas.drawBitmap(previousImage, mp, mPaint);
        }

        canvas.restore();
    } else {
        drawShadow(canvas, mImageBounds); // as needed
        canvas.drawBitmap(image, m, mPaint);
    }

    canvas.restore();
}