Android Image Shadow processing analysis!

Source: Internet
Author: User

Android Image Shadow processing analysis!

Recently I am working on an Android bitmap shadow processing result. I will summarize my ideas today:

The analysis is as follows:

The Android sdk provides the BlurMaskFilter tool class to add shadow effects to images. The Code is as follows:
-/**
* This takes a mask, and blurs its edge by the specified radius. Whether or
* Or not to include the original mask, and whether the blur goes outside,
* Inside, or straddles, the original mask's border, is controlled by
* Blur enum.
*/
'Public class BlurMaskFilter extends MaskFilter {

public enum Blur {    NORMAL(0),  //!< blur inside and outside of the original border    SOLID(1),   //!< include the original mask, blur outside    OUTER(2),   //!< just blur outside the original border    INNER(3);   //!< just blur inside the original border    Blur(int value) {        native_int = value;    }    final int native_int;}/** * Create a blur maskfilter. * * @param radius The radius to extend the blur from the original mask. Must be > 0. * @param style  The Blur to use * @return       The new blur maskfilter */public BlurMaskFilter(float radius, Blur style) {    native_instance = nativeConstructor(radius, style.native_int);}private static native int nativeConstructor(float radius, int style);

}
'---

Note:

BlurMaskFilter can blur the edge of a bitmap within the specified radius. Whether the original mask is included or not. Whether to Blur the bitmap inside or outside the bitmap or crossing the inside or outside of the bitmap can be determined by initializing different parameters for enumeration Blur in the code. The meanings of parameters corresponding to Blur are as follows: (See here for translation)
NORMAL (0 ),//! <The mask is displayed inside and outside the target. The mask is displayed from the edge to the inside and outside the target to the radius width away from the edge, and the color obtained at the target edge is displayed at the same time.
SOLID (1 ),//! <Show the mask outside the target, from the edge to the target outside to the radius width from the edge, and this section displays the color obtained from the target edge and the target
OUTER (2 ),//! <Show the mask outside the target, from the edge to the target outside to the radius width from the edge, and this section displays the color obtained from the target edge, not the target
INNER (3 );//! <Display masks in the target, from the edge to the target to the radius width away from the edge. radius is a value of BlurMaskFilter initialized to construct a BlurMaskFilter object and then you can use android. graphics. the setMaskFilter method of the Paint class is passed to the Paint brush object. We can use this shadow Paint brush to process the edge of the bitmap.

Now we have a paint brush that can be blurred. How can we use this paint brush to process the edge of a specified bitmap? We also need to check another tool class provided by the SDK. This class is an extractAlpha method of android. graphics. Bitmap. The Code is as follows:

  /**     * Returns a new bitmap that captures the alpha values of the original.     * These values may be affected by the optional Paint parameter, which     * can contain its own alpha, and may also contain a MaskFilter which     * could change the actual dimensions of the resulting bitmap (e.g.     * a blur maskfilter might enlarge the resulting bitmap). If offsetXY     * is not null, it returns the amount to offset the returned bitmap so     * that it will logically align with the original. For example, if the     * paint contains a blur of radius 2, then offsetXY[] would contains     * -2, -2, so that drawing the alpha bitmap offset by (-2, -2) and then     * drawing the original would result in the blur visually aligning with     * the original.     *      * 

The initial density of the returned bitmap is the same as the original's. * * @param paint Optional paint used to modify the alpha values in the * resulting bitmap. Pass null for default behavior. * @param offsetXY Optional array that returns the X (index 0) and Y * (index 1) offset needed to position the returned bitmap * so that it visually lines up with the original. * @return new bitmap containing the (optionally modified by paint) alpha * channel of the original bitmap. This may be drawn with * Canvas.drawBitmap(), where the color(s) will be taken from the * paint that is passed to the draw call. */ public Bitmap extractAlpha(Paint paint, int[] offsetXY) { checkRecycled("Can't extractAlpha on a recycled bitmap"); int nativePaint = paint != null ? paint.mNativePaint : 0; Bitmap bm = nativeExtractAlpha(mNativeBitmap, nativePaint, offsetXY); if (bm == null) { throw new RuntimeException("Failed to extractAlpha on Bitmap"); } bm.mDensity = mDensity; return bm; }

Note:

The function of this method is to return a new bitmap. This bitmap only obtains the transparency value Alpha of the original bitmap, but does not have RGB. Therefore, the bitmap we see is a black bitmap. For more information about bitmap ARGB, see here. There are two parameters in this method: paint and offsetXY. We can pass in the paint brush with shadow effect obtained above, so that the new bitmap edge will have shadow processing; offset offsetXY is used to specify the radius Range of the paint brush's shadow effect on the edge of the bitmap. This value is determined by the radius parameter passed when the BlurMaskFilter is constructed above. The size of the new bitmap may be larger than that of the original bitmap. Assume that the radius value passed in when BlurMaskFilter is constructed is 6 and the original bitmap size is 144x144. The new bitmap size is (144 + 6x2) x (144 + 6x2 ). Offset offsetXY [0] = offsetXY [1] =-6.

Original bitmap

Obtain the new bitmap after the original bitmap transparent channel

Now we have obtained a shadow bitmap with shadow effects on the edge. We define it as shadowAlphaBitmap, but this bitmap is not the expected final effect. Next we need to splice this bitmap with the original bitmap.

The specific idea is as follows:

First, define a new canvas to initialize an rgba bitmap for this canvas. The size of the bitmap is consistent with that of shadowAlphaBitmap. Here, I will give you more details. The bitmap initialized for canvas must be of the isMutable type, meaning that the pixels of this bitmap can be modified. Otherwise, an error will be reported. For example, bitmap loaded by resource id cannot be changed or initialized to canvas. The Canvas source code is as follows:
/**     * Construct a canvas with the specified bitmap to draw into. The bitmap     * must be mutable.     *      * 

The initial target density of the canvas is the same as the given * bitmap's density. * * @param bitmap Specifies a mutable bitmap for the canvas to draw into. */ public Canvas(Bitmap bitmap) { if (!bitmap.isMutable()) { throw new IllegalStateException("Immutable bitmap passed to Canvas constructor"); } throwIfRecycled(bitmap); mNativeCanvas = initRaster(bitmap.ni()); mFinalizer = new CanvasFinalizer(mNativeCanvas); mBitmap = bitmap; mDensity = bitmap.mDensity; }

Draw shadowAlphaBitmap to the canvas and convert the original bitmap to the canvas. When drawing the original bitmap, note that the original bitmap is smaller than shadowAlphaBitmap, smaller in length and width-offsetXY [0], and-offsetXY [1]. therefore, we need to translate the original bitmap to center the original bitmap in the canvas. In this case, the original bitmap and the canvas are the shadows we expect to see.

The Code is as follows:

   private Bitmap getShadowBitmap(Bitmap srcBitmap){        Paint shadowPaint = new Paint();        BlurMaskFilter blurMaskFilter = new BlurMaskFilter(6,BlurMaskFilter.Blur.NORMAL);        shadowPaint.setMaskFilter(blurMaskFilter);        int[] offsetXY = new int[2];        Bitmap shadowBitmap = srcBitmap.extractAlpha(shadowPaint,offsetXY);        Bitmap canvasBgBitmap = Bitmap.createBitmap(                shadowBitmap.getWidth(), shadowBitmap.getHeight(), Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas();        canvas.setBitmap(canvasBgBitmap);        canvas.drawBitmap(shadowBitmap, 0, 0, shadowPaint);        canvas.drawBitmap(srcBitmap, -offsetXY[0], -offsetXY[1], null);        shadowBitmap.recycle();        return canvasBgBitmap;    }

The last obtained edge shadow bitmap

Summary:
To obtain the image shadow effect, you must understand the following knowledge points:
-Usage of BlurMaskFilter.
-The meaning and usage of the extractAlpha method provided by Bitmap.
-Basic Support for bitmap ARGB
-Use Canvas to modify bitmap knowledge

Code github address

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.