package tech.starwin.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.util.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.SoftReference;

/**
 * Created by Sikang on 2017/7/11.
 */

public class BitmapUtils {
    /**
     * Bitmap裁剪
     */
    public static Bitmap cropBitmap(Bitmap bitmap, int left, int top, int width, int height) {
        if (null == bitmap || width <= 0 || height < 0) {
            return null;
        }
        int widthOrg = bitmap.getWidth();
        int heightOrg = bitmap.getHeight();
        if (widthOrg >= width && heightOrg >= height) {
            try {
                bitmap = Bitmap.createBitmap(bitmap, left, top, width, height);
            } catch (Exception e) {
                return null;
            }
        }
        return bitmap;
    }


    /**
     * 缩放图片到指定大小（保持比例）
     */
    public static Bitmap scaleBitmap(Bitmap bitmap, int w, int h) {
        if (w == 0 || h == 0)
            return bitmap;
        Bitmap BitmapOrg = bitmap;
        int width = BitmapOrg.getWidth();
        int height = BitmapOrg.getHeight();
        if (w == width && h == height)
            return bitmap;

        float scaleWidth = ((float) w) / width;
        float scaleHeight = ((float) h) / height;
        float scale = scaleWidth > scaleHeight ? scaleWidth : scaleHeight;
        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);
        Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
                height, matrix, true);
        return resizedBitmap;
    }

    /**
     * 缩放图片到指定大小（保持比例）
     */
    public static Bitmap scaleBitmap(Bitmap bitmap, float scale) {
        if (scale == 0 || scale == 1) {
            return bitmap;
        }

        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

    /**
     * 从SD卡中加载图片中心区域
     */
    public static Bitmap loadBitmapCenterByPath(String path, int width, int height) {
        Bitmap bitmap = loadBitmapByPath(path, width, height);//先按比例缩小到最小倍数，然后加载图片到内存
        if (bitmap == null)
            return null;
        bitmap = scaleBitmap(bitmap, width, height);//再将加载好的图片缩放到指定大小
        return cropBitmapCenter(bitmap, width, height);
    }


    /**
     * 按指定尺寸加载SD卡 中的图片(指定宽高保持比例缩放)
     */
    public static Bitmap loadBitmapByPath(String path, float width, float height) {
        try {
            int degree = readPictureDegree(path);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;//不加载bitmap到内存中
            BitmapFactory.decodeFile(path, options);
            float outWidth = options.outWidth;
            float outHeight = options.outHeight;
            options.inDither = false;
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
            options.inSampleSize = 1;

            if (outWidth != 0 && outHeight != 0 && width != 0 && height != 0) {
                int scaleX = (int) (outWidth / width);
                int scaleY = (int) (outHeight / height);
                options.inSampleSize = scaleX < scaleY ? scaleX : scaleY;
            }
            options.inJustDecodeBounds = false;
            Bitmap bitmap = BitmapFactory.decodeFile(path, options);
            //把图片旋转为正的方向
            return rotateBitmap(bitmap, degree);
        } catch (NullPointerException e) {
            return null;
        }

    }


    /**
     * 取中间区域
     */
    public static Bitmap cropBitmapCenter(Bitmap bitmap, int width, int height) {
        if (bitmap == null || width <= 0 || height <= 0) {
            return null;
        }
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        if (w <= width && h <= height)
            return bitmap;
        if (width > w)
            width = w;
        if (height > h)
            height = h;

        int top, left;
        if (w <= width)
            left = 0;
        else
            left = (w - width) / 2;


        if (h <= height)
            top = 0;
        else
            top = (h - height) / 2;

        return cropBitmap(bitmap, left, top, width, height);
    }

    /**
     * 读取图片属性：旋转的角度
     *
     * @param path 图片绝对路径
     * @return degree旋转的角度
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 保存图片到本地
     *
     * @param quality 质量压缩比例
     */
    public static File saveBitmapToSDCard(Bitmap mBitmap, File file, int quality) {
        if (mBitmap == null)
            return null;
        try {
            if (file.exists())
                file.delete();
            file.createNewFile();

        } catch (IOException e) {
            e.printStackTrace();
        }
        FileOutputStream fOut = null;
        try {
            fOut = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        mBitmap.compress(Bitmap.CompressFormat.JPEG, quality, fOut);
        try {
            fOut.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (file.exists())
            return file;
        return null;
    }

    /**
     * 将相机图片转为横向
     */
    public static Bitmap getHorizontalPhoto(Bitmap bitmap) {
        if (bitmap.getWidth() < bitmap.getHeight()) {
            return rotateBitmap(bitmap, -90);
        }
        return bitmap;
    }

    /**
     * 图片旋转
     */
    public static Bitmap rotateBitmap(Bitmap bitmap, float degrees) {
        Matrix matrix = new Matrix();
        matrix.reset();
        matrix.setRotate(degrees);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix,
                true);
    }


    /**
     * 将图片数据压缩，并转为bitmap
     */
    public static Bitmap getBitmapWithMaxLimit(byte[] data, final int maxSquerSize, final int maxFileSize) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inPreferredConfig = Bitmap.Config.RGB_565;
        opts.inPurgeable = true;
        opts.inInputShareable = true;
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        SoftReference<Bitmap> temp = new SoftReference<>(BitmapFactory.decodeStream(byteArrayInputStream, null, opts));

        SoftReference<Bitmap> result = temp;

        final float BITMAP_MAX_SQUARE_SIZE_FLOAT = maxSquerSize * 1.0f;

        if (temp.get().getWidth() > maxSquerSize || temp.get().getHeight() > maxSquerSize) {
            //缩小到框内
            float proportion = BITMAP_MAX_SQUARE_SIZE_FLOAT / Math.max(temp.get().getWidth(), temp.get().getHeight());

            int outWidth = ((int) (temp.get().getWidth() * proportion));
            int outHeight = ((int) (temp.get().getHeight() * proportion));

            result = new SoftReference<>(Bitmap.createScaledBitmap(temp.get(), outWidth, outHeight, true));

            temp.clear();
        }

        if (data.length > maxFileSize) {

            float proportion = 1.0f * maxFileSize / data.length;
            int width = (int) (result.get().getWidth() * proportion);
            int height = (int) (result.get().getHeight() * proportion);
            SoftReference<Bitmap> scaled = new SoftReference<>(Bitmap.createScaledBitmap(result.get(), width, height, false));

            result.clear();
            return scaled.get();
        }

        return result.get();
    }


    /**
     * bitmap转为base64
     *
     * @param bitmap
     * @return
     */
    public static String bitmapToBase64(Bitmap bitmap) {

        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * base64转为bitmap
     *
     * @param base64Data
     * @return
     */
    public static Bitmap base64ToBitmap(String base64Data) {
        byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    /**
     * Drawable转Bitmap
     */
    public static Bitmap drawableToBmp(Drawable drawable) {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
        return bitmapDrawable.getBitmap();
    }


}
