BitmapKit icon indicating copy to clipboard operation
BitmapKit copied to clipboard

:fire: Android bitmap clip, scale, blur, rotate, shadow, shader and so on. java and jni realize. 图片裁剪、缩放、模糊、旋转、阴影、渐变的java和jni实现。

AndroidBitmapOperations

Android bitmap clip, scale, blur, rotate and so on. java and jni realize. 图片裁剪、缩放、模糊、旋转的java和jni实现。

1、Bitmap碎片复用的情况下任意裁剪

裁剪讲解博客地址:https://www.jianshu.com/p/329746c1789f

这里说的碎片复用就是在图片的裁剪过程中创建丢弃大量的Bitmap对象,如果不对这些Bitmap进行复用会造成多余的内存浪费,造成内存抖动

1.1 Bitmap裁剪保留下部分:

说明 前后效果对比
裁剪保留下部分,取一半高度 TIM图片20180228220755.png 裁剪后: Screenshot_2018-02-28-21-59-16-052_BitmapKit.png

裁剪代码:

    /**
     * 裁剪一定高度保留下面
     * @param srcBitmap
     * @param needHeight
     * @param recycleSrc 是否回收原图
     * @return
     */
    @DebugLog
    public static Bitmap cropBitmapBottom(Bitmap srcBitmap, int needHeight, boolean recycleSrc) {

        Log.d("danxx", "cropBitmapBottom before h : "+srcBitmap.getHeight());

        /**裁剪保留下部分的第一个像素的Y坐标*/
        int needY = srcBitmap.getHeight() - needHeight;

        /**裁剪关键步骤*/
        Bitmap cropBitmap = Bitmap.createBitmap(srcBitmap,0,needY,srcBitmap.getWidth(),needHeight);

        Log.d("danxx", "cropBitmapBottom after h : "+cropBitmap.getHeight());

        /**回收之前的Bitmap*/
        if (recycleSrc && srcBitmap != null && !srcBitmap.equals(cropBitmap) && !srcBitmap.isRecycled()) {
            GlideBitmapPool.putBitmap(srcBitmap);
        }

        return cropBitmap;
    }

1.2 Bitmap裁剪保留左部分:

说明 前后效果对比
裁剪保留左部分,取一半宽度 TIM图片20180228220755.png 裁剪后: Screenshot_2018-02-28-21-59-34-089_BitmapKit.png

裁剪代码:

    /**
     * 裁剪一定高度保留左边
     * @param srcBitmap
     * @param needWidth
     * @return
     */
    @DebugLog
    public static Bitmap cropBitmapLeft(Bitmap srcBitmap, int needWidth, boolean recycleSrc) {

        Log.d("danxx", "cropBitmapLeft before w : "+srcBitmap.getWidth());

        /**裁剪关键步骤*/
        Bitmap cropBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, needWidth, srcBitmap.getHeight());

        Log.d("danxx", "cropBitmapLeft after w : "+cropBitmap.getWidth());

        /**回收之前的Bitmap*/
        if (recycleSrc && srcBitmap != null && !srcBitmap.equals(cropBitmap) && !srcBitmap.isRecycled()) {
            GlideBitmapPool.putBitmap(srcBitmap);
        }

        return cropBitmap;
    }

1.3 Bitmap裁剪保留右部分:

说明 前后效果对比
裁剪保留右部分,取一半宽度 TIM图片20180228220755.png 裁剪后: Screenshot_2018-02-28-22-00-03-095_BitmapKit.png

裁剪代码:

    /**
     * 裁剪一定高度保留左边
     * @param srcBitmap
     * @param needWidth
     * @return
     */
    @DebugLog
    public static Bitmap cropBitmapRight(Bitmap srcBitmap, int needWidth, boolean recycleSrc) {

        Log.d("danxx", "cropBitmapRight before w : "+srcBitmap.getWidth());

        int needX = srcBitmap.getWidth() - needWidth;

        /**裁剪关键步骤*/
        Bitmap cropBitmap = Bitmap.createBitmap(srcBitmap, needX, 0, needWidth, srcBitmap.getHeight());

        Log.d("danxx", "cropBitmapRight after w : "+cropBitmap.getWidth());

        /**回收之前的Bitmap*/
        if (recycleSrc && srcBitmap != null && !srcBitmap.equals(cropBitmap) && !srcBitmap.isRecycled()) {
            GlideBitmapPool.putBitmap(srcBitmap);
        }

        return cropBitmap;
    }

1.4 Bitmap裁剪保留上部分:

说明 前后效果对比
裁剪保留上部分,取一半高度 TIM图片20180228220755.png 裁剪后: Screenshot_2018-02-28-21-59-49-769_BitmapKit.png

裁剪代码:

   /**
     * 裁剪一定高度保留下面
     * @param srcBitmap
     * @param needHeight
     * @param recycleSrc 是否回收原图
     * @return
     */
    @DebugLog
    public static Bitmap cropBitmapTop(Bitmap srcBitmap, int needHeight, boolean recycleSrc) {

        Log.d("danxx", "cropBitmapBottom before h : "+srcBitmap.getHeight());

        /**裁剪保留上部分的第一个像素的Y坐标*/
        int needY = 0;

        /**裁剪关键步骤*/
        Bitmap cropBitmap = Bitmap.createBitmap(srcBitmap,0,needY,srcBitmap.getWidth(),needHeight);

        Log.d("danxx", "cropBitmapBottom after h : "+cropBitmap.getHeight());

        /**回收之前的Bitmap*/
        if (recycleSrc && srcBitmap != null && !srcBitmap.equals(cropBitmap) && !srcBitmap.isRecycled()) {
            GlideBitmapPool.putBitmap(srcBitmap);
        }

        return cropBitmap;
    }


1.5 Bitmap指定参数任意裁剪:

说明 前后效果对比
指定参数任意裁剪 TIM图片20180228220755.png 裁剪后: Screenshot_2018-02-28-22-00-13-606_BitmapKit.png

裁剪代码:

    /**
     * 自定义裁剪,根据第一个像素点(左上角)X和Y轴坐标和需要的宽高来裁剪
     * @param srcBitmap
     * @param firstPixelX
     * @param firstPixelY
     * @param needWidth
     * @param needHeight
     * @param recycleSrc
     * @return
     */
    @DebugLog
    public static Bitmap cropBitmapCustom(Bitmap srcBitmap, int firstPixelX, int firstPixelY, int needWidth, int needHeight, boolean recycleSrc) {

        Log.d("danxx", "cropBitmapRight before w : "+srcBitmap.getWidth());
        Log.d("danxx", "cropBitmapRight before h : "+srcBitmap.getHeight());

        if(firstPixelX + needWidth > srcBitmap.getWidth()){
            needWidth = srcBitmap.getWidth() - firstPixelX;
        }

        if(firstPixelY + needHeight > srcBitmap.getHeight()){
            needHeight = srcBitmap.getHeight() - firstPixelY;
        }

        /**裁剪关键步骤*/
        Bitmap cropBitmap = Bitmap.createBitmap(srcBitmap, firstPixelX, firstPixelY, needWidth, needHeight);

        Log.d("danxx", "cropBitmapRight after w : "+cropBitmap.getWidth());
        Log.d("danxx", "cropBitmapRight after h : "+cropBitmap.getHeight());


        /**回收之前的Bitmap*/
        if (recycleSrc && srcBitmap != null && !srcBitmap.equals(cropBitmap) && !srcBitmap.isRecycled()) {
            GlideBitmapPool.putBitmap(srcBitmap);
        }

        return cropBitmap;
    }