zoukankan      html  css  js  c++  java
  • ImageUtils

    JavaSE

    package com.easystructure.utils.system;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.imageio.ImageIO;
    
    import com.sun.image.codec.jpeg.JPEGCodec;
    import com.sun.image.codec.jpeg.JPEGEncodeParam;
    import com.sun.image.codec.jpeg.JPEGImageEncoder;
    
    @SuppressWarnings("all")
    public class ImageUtils {
    
     /**
      * 把图片印刷到图片上
      * 
      * @param pressImg
      *            -- 水印文件
      * @param targetImg
      *            -- 目标文件
      * @param intAlign
      *            --位置类型
      */
     public final static void pressImage(String pressImg, String targetImg, int intAlign) {
      
      try {
       // 目标文件
       File _file = new File(targetImg);
       Image src = ImageIO.read(_file);
       int wideth = src.getWidth(null);
       int height = src.getHeight(null);
       BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
       Graphics2D g = image.createGraphics();
       g.drawImage(src, 0, 0, wideth, height, null);
    
       // 水印文件
       File _filebiao = new File(pressImg);
       Image src_biao = ImageIO.read(_filebiao);
       int wideth_biao = src_biao.getWidth(null);
       int height_biao = src_biao.getHeight(null);
       if (intAlign == 1) {
        g.drawImage(src_biao, 5, 10, wideth_biao, height_biao, null);
       } else if (intAlign == 2) {
        g.drawImage(src_biao, (wideth - wideth_biao) / 2 - 5, 10, wideth_biao, height_biao, null);
       } else if (intAlign == 3) {
        g.drawImage(src_biao, wideth - wideth_biao - 5, 10, wideth_biao, height_biao, null);
       } else if (intAlign == 4) {
        g.drawImage(src_biao, 5, (height - height_biao) / 2 - 10, wideth_biao, height_biao, null);
       } else if (intAlign == 5) {
        g.drawImage(src_biao, (wideth - wideth_biao) / 2 - 5, (height - height_biao) / 2 - 10, wideth_biao, height_biao, null);
       } else if (intAlign == 6) {
        g.drawImage(src_biao, wideth - wideth_biao - 5, (height - height_biao) / 2 - 10, wideth_biao, height_biao, null);
       } else if (intAlign == 7) {
        g.drawImage(src_biao, 5, height - height_biao - 10, wideth_biao, height_biao, null);
       } else if (intAlign == 8) {
        g.drawImage(src_biao, (wideth - wideth_biao) / 2 - 5, height - height_biao - 10, wideth_biao, height_biao, null);
       } else if (intAlign == 9) {
        g.drawImage(src_biao, wideth - wideth_biao - 5, height - height_biao - 10, wideth_biao, height_biao, null);
       }
       // 水印文件结束
       g.dispose();
       FileOutputStream out = new FileOutputStream(targetImg);
       JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
       encoder.encode(image);
       out.close();
      } catch (Exception e) {
       e.printStackTrace();
      }
     }
    
     /**
      * 
      * @param strImageText
      * @param fm
      * @return
      * @author googol Feb 9, 2006
      */
     public static int getStringWidth(String strImageText, FontMetrics fm) {
      int intReturn = 0;
      int intCount = strImageText.length();
      char chrImageText[] = strImageText.toCharArray();
      for (int i = 0; i < intCount; i++) {
       int charWidth = fm.charWidth(chrImageText[i]);
       intReturn += charWidth;
      }
    
      return intReturn += 10;
     }
    
     /** */
     /**
      * 打印文字水印图片
      * 
      * @param pressText
      *            --文字
      * @param targetImg
      *            -- 目标图片
      * @param fontName
      *            -- 字体名
      * @param fontStyle
      *            -- 字体样式
      * @param color
      *            -- 字体颜色
      * @param fontSize
      *            -- 字体大小
      * @param intAlign
      *            --位置类型
      */
    
     public static void pressText(String pressText, String targetImg, String fontName, int fontStyle, Color color, int fontSize, int intAlign) {
      try {
       File _file = new File(targetImg);
       Image src = ImageIO.read(_file);
       int wideth = src.getWidth(null);
       int height = src.getHeight(null);
       BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
       Graphics2D g = image.createGraphics();
       g.drawImage(src, 0, 0, wideth, height, null);
       g.setColor(color);
       g.setFont(new Font(fontName, fontStyle, fontSize));
       int intWidth = getStringWidth(pressText, g.getFontMetrics());
       if (wideth > intWidth) {
        if (intAlign == 1) {
         g.drawString(pressText, 5, 20);
        } else if (intAlign == 2) {
         g.drawString(pressText, (wideth - intWidth) / 2 - 5, 20);
        } else if (intAlign == 3) {
         g.drawString(pressText, wideth - intWidth - 5, 20);
        } else if (intAlign == 4) {
         g.drawString(pressText, 5, height / 2 - 10);
        } else if (intAlign == 5) {
         g.drawString(pressText, (wideth - intWidth) / 2 - 5, height / 2 - 10);
        } else if (intAlign == 6) {
         g.drawString(pressText, wideth - intWidth - 5, height / 2 - 10);
        } else if (intAlign == 7) {
         g.drawString(pressText, 5, height - 10);
        } else if (intAlign == 8) {
         g.drawString(pressText, (wideth - intWidth) / 2 - 5, height - 10);
        } else if (intAlign == 9) {
         g.drawString(pressText, wideth - intWidth - 5, height - 10);
        }
       } else {
        g.drawString(pressText, 0, height - 10);
       }
       g.dispose();
       FileOutputStream out = new FileOutputStream(targetImg);
       JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
       encoder.encode(image);
       out.close();
      } catch (Exception e) {
       System.out.println(e);
      }
     }
    
     /**
      * 只限制宽度生成缩略图,按比例缩放,如果原图宽度比需要生成的图的宽度还小,则简单拷贝一张图
      * 
      * @author Dennis
      * 
      *         2009-11-17 下午04:41:55
      */
     public static void makeMiniature(String strPicturePath, String strOutPath, int intMinWidth) {
      File _file = new File(strPicturePath);
      Image src;
      try {
       src = ImageIO.read(_file);
       int width = src.getWidth(null);
       int height = src.getHeight(null);
       if (width <= intMinWidth) {
        // 直接copy
        makeMiniature(strPicturePath, strOutPath, width, height);
       } else {
        // 得到缩放比例
        float scale = (float) intMinWidth / width;
        makeMiniature(strPicturePath, strOutPath, intMinWidth, (int) (height * scale - 1));
       }
    
      } catch (IOException e) {
       System.out.println(e);
      }
     }
    
     /**
      * 产生一个缩略
      * 
      * @param strPicturePath
      *            原图片位置
      * @param strOutPath
      *            生成图片的位置 2009-11-17 下午04:43:50
      */
     public static void makeMiniature(String strPicturePath, String strOutPath, int intMinWidth, int intMinHeight) {
    
      try {
       String imageFile = strPicturePath;
       File file = new File(imageFile);
    
       BufferedImage im = null;
       InputStream imageIn = new FileInputStream(file);
    
       im = ImageIO.read(imageIn);
       int minh = intMinHeight, minw = intMinWidth;
    
       BufferedImage imout = new BufferedImage(minw, minh, 1);
       Graphics g = imout.getGraphics();
       g.drawImage(im, 0, 0, minw, minh, null);
    
       imageIn.close();
    
       File out = new File(strOutPath);
       if (strOutPath.endsWith(".JPG") || strOutPath.endsWith(".jpg")) {
        ImageIO.write(imout, "jpg", out);
    
       } else if (strOutPath.endsWith(".GIF") || strOutPath.endsWith(".gif")) {
        ImageIO.write(imout, "gif", out);
       }
      } catch (Exception ex) {
       ex.printStackTrace();
      }
     }
    
     
     /**
      * 压缩图片文件<br>
      * 先保存原文件,再压缩、上传
      * 
      * @param oldFile
      *            要进行压缩的文件全路径
      * @param width
      *            宽度
      * @param height
      *            高度
      * @param quality
      *            质量
      * @param smallIcon
      *            小图片的后缀
      * @return 返回压缩后的文件的全路径
      */
     public static String zipImageFile(String oldFile, int width, int height, float quality, String smallIcon) {
      if (oldFile == null)
       return null;
      String newImage = null;
      try {
       /** 对服务器上的临时文件进行处理 */
       Image srcFile = ImageIO.read(new File(oldFile));
       double rate1 = ((double) srcFile.getWidth(null)) / (double) width + 0.1;
       double rate2 = ((double) srcFile.getHeight(null)) / (double) width + 0.1;
       double rate = rate1 > rate2 ? rate1 : rate2;
       width = (int) (((double) srcFile.getWidth(null)) / rate);
       width = (int) (((double) srcFile.getHeight(null)) / rate);
    
       /** 宽,高设定 */
       BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
       tag.getGraphics().drawImage(srcFile, 0, 0, width, height, null);
       String filePrex = oldFile.substring(0, oldFile.indexOf('.'));
       /** 压缩后的文件名 */
       newImage = filePrex + smallIcon + oldFile.substring(filePrex.length());
    
       /** 压缩之后临时存放位置 */
       FileOutputStream out = new FileOutputStream(newImage);
    
       JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
       JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
       /** 压缩质量 */
       jep.setQuality(quality, true);
       encoder.encode(tag, jep);
       out.close();
    
      } catch (FileNotFoundException e) {
       e.printStackTrace();
      } catch (IOException e) {
       e.printStackTrace();
      }
      return newImage;
     }
    
     /**
      * 经过缩略图算法的压缩。存放生成图片的路径同源图片。
      * 
      * @param oldFile
      * @param width
      * @param height
      * @param smallIcon
      */
     public static void zipImageFileSameOldPath(String oldFile, int intMinWidth, int intMinHeight, String smallIcon) {
      
      String strPicturePath = oldFile;
      String strOutPath = CommonUtils.addStrToFileName(strPicturePath, smallIcon);
      zipImageFileDifferPath(strPicturePath, strOutPath, intMinWidth, intMinHeight);
     }
    
     /**
      * 经过缩略图算法的压缩。存放生成图片的路径为指定路径。
      * 
      * @param oldFile
      * @param width
      * @param height
      * @param smallIcon
      */
     public static void zipImageFileDifferPath(String oldFilePath, String newFilePath, int intMinWidth, int intMinHeight) {
      
      BufferedImage im = null;
      BufferedImage imout = null;
      int minh = intMinHeight;
      int minw = intMinWidth;
      try {
       File file = new File(oldFilePath);
       InputStream imageIn = new FileInputStream(file);
       im = ImageIO.read(imageIn);
          imout = new ImageScale().imageZoomOut(im, minw, minh);
       imageIn.close();
    
       File out = new File(newFilePath);
       if (newFilePath.endsWith(".JPG") || newFilePath.endsWith(".jpg")) {
        ImageIO.write(imout, "jpg", out);
       } else if (newFilePath.endsWith(".GIF") || newFilePath.endsWith(".gif")) {
        ImageIO.write(imout, "gif", out);
       }
      } catch (Exception ex) {
       ex.printStackTrace();
      }
     }
     
     
     public static void main(String[] args) {
      // pressImage("F:/bisonte.png", "F:/123.jpg", 9);
      pressText("Dennis", "F:/123.jpg", "宋体", Font.PLAIN, Color.RED, 15, 6);
      // createMark("F:/123.jpg", "mmmmnn", Color.RED, 15);
     }
    
    }
    View Code

    http://blog.csdn.net/googolplex/article/details/6724887

    Android

    bitmap2Bytes, bytes2Bitmap       : bitmap与byteArr互转
    drawable2Bitmap, bitmap2Drawable : drawable与bitmap互转
    drawable2Bytes, bytes2Drawable   : drawable与byteArr互转
    getBitmap                        : 获取bitmap
    scale                            : 缩放图片
    clip                             : 裁剪图片
    skew                             : 倾斜图片
    rotate                           : 旋转图片
    getRotateDegree                  : 获取图片旋转角度
    toRound                          : 转为圆形图片
    toRoundCorner                    : 转为圆角图片
    fastBlur                         : 快速模糊
    renderScriptBlur                 : renderScript模糊图片
    stackBlur                        : stack模糊图片
    addFrame                         : 添加颜色边框
    addReflection                    : 添加倒影
    addTextWatermark                 : 添加文字水印
    addImageWatermark                : 添加图片水印
    toAlpha                          : 转为alpha位图
    toGray                           : 转为灰度图片
    save                             : 保存图片
    isImage                          : 根据文件名判断文件是否为图片
    getImageType                     : 获取图片类型
    compressByScale                  : 按缩放压缩
    compressByQuality                : 按质量压缩
    compressBySampleSize             : 按采样大小压缩
    import android.annotation.TargetApi;
    import android.content.Context;
    import android.content.res.Resources;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.CompressFormat;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.ColorMatrix;
    import android.graphics.ColorMatrixColorFilter;
    import android.graphics.LinearGradient;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.PixelFormat;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffColorFilter;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.graphics.Shader;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.graphics.drawable.NinePatchDrawable;
    import android.media.ExifInterface;
    import android.os.Build;
    import android.renderscript.Allocation;
    import android.renderscript.Element;
    import android.renderscript.RenderScript;
    import android.renderscript.ScriptIntrinsicBlur;
    import android.support.annotation.FloatRange;
    import android.support.annotation.IntRange;
    import android.view.View;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileDescriptor;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    /**
     * <pre>
     *     author: Blankj
     *     blog  : http://blankj.com
     *     time  : 2016/8/12
     *     desc  : 图片相关工具类
     * </pre>
     */
    public class ImageUtils {
    
        private ImageUtils() {
            throw new UnsupportedOperationException("u can't instantiate me...");
        }
    
        /**
         * bitmap转byteArr
         *
         * @param bitmap bitmap对象
         * @param format 格式
         * @return 字节数组
         */
        public static byte[] bitmap2Bytes(Bitmap bitmap, CompressFormat format) {
            if (bitmap == null) return null;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(format, 100, baos);
            return baos.toByteArray();
        }
    
        /**
         * byteArr转bitmap
         *
         * @param bytes 字节数组
         * @return bitmap
         */
        public static Bitmap bytes2Bitmap(byte[] bytes) {
            return (bytes == null || bytes.length == 0) ? null : BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        }
    
        /**
         * drawable转bitmap
         *
         * @param drawable drawable对象
         * @return bitmap
         */
        public static Bitmap drawable2Bitmap(Drawable drawable) {
            if (drawable instanceof BitmapDrawable) {
                return ((BitmapDrawable) drawable).getBitmap();
            } else if (drawable instanceof NinePatchDrawable) {
                Bitmap bitmap = Bitmap.createBitmap(
                        drawable.getIntrinsicWidth(),
                        drawable.getIntrinsicHeight(),
                        drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
                Canvas canvas = new Canvas(bitmap);
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                drawable.draw(canvas);
                return bitmap;
            } else {
                return null;
            }
        }
    
        /**
         * bitmap转drawable
         *
         * @param res    resources对象
         * @param bitmap bitmap对象
         * @return drawable
         */
        public static Drawable bitmap2Drawable(Resources res, Bitmap bitmap) {
            return bitmap == null ? null : new BitmapDrawable(res, bitmap);
        }
    
        /**
         * drawable转byteArr
         *
         * @param drawable drawable对象
         * @param format   格式
         * @return 字节数组
         */
        public static byte[] drawable2Bytes(Drawable drawable, CompressFormat format) {
            return drawable == null ? null : bitmap2Bytes(drawable2Bitmap(drawable), format);
        }
    
        /**
         * byteArr转drawable
         *
         * @param res   resources对象
         * @param bytes 字节数组
         * @return drawable
         */
        public static Drawable bytes2Drawable(Resources res, byte[] bytes) {
            return res == null ? null : bitmap2Drawable(res, bytes2Bitmap(bytes));
        }
    
        /**
         * view转Bitmap
         *
         * @param view 视图
         * @return bitmap
         */
        public static Bitmap view2Bitmap(View view) {
            if (view == null) return null;
            Bitmap ret = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(ret);
            Drawable bgDrawable = view.getBackground();
            if (bgDrawable != null) {
                bgDrawable.draw(canvas);
            } else {
                canvas.drawColor(Color.WHITE);
            }
            view.draw(canvas);
            return ret;
        }
    
        /**
         * 计算采样大小
         *
         * @param options   选项
         * @param maxWidth  最大宽度
         * @param maxHeight 最大高度
         * @return 采样大小
         */
        private static int calculateInSampleSize(BitmapFactory.Options options, int maxWidth, int maxHeight) {
            if (maxWidth == 0 || maxHeight == 0) return 1;
            int height = options.outHeight;
            int width = options.outWidth;
            int inSampleSize = 1;
            while ((height >>= 1) >= maxHeight && (width >>= 1) >= maxWidth) {
                inSampleSize <<= 1;
            }
            return inSampleSize;
        }
    
        /**
         * 获取bitmap
         *
         * @param file 文件
         * @return bitmap
         */
        public static Bitmap getBitmap(File file) {
            if (file == null) return null;
            InputStream is = null;
            try {
                is = new BufferedInputStream(new FileInputStream(file));
                return BitmapFactory.decodeStream(is);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return null;
            } finally {
                CloseUtils.closeIO(is);
            }
        }
    
        /**
         * 获取bitmap
         *
         * @param file      文件
         * @param maxWidth  最大宽度
         * @param maxHeight 最大高度
         * @return bitmap
         */
        public static Bitmap getBitmap(File file, int maxWidth, int maxHeight) {
            if (file == null) return null;
            InputStream is = null;
            try {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                is = new BufferedInputStream(new FileInputStream(file));
                BitmapFactory.decodeStream(is, null, options);
                options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
                options.inJustDecodeBounds = false;
                return BitmapFactory.decodeStream(is, null, options);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return null;
            } finally {
                CloseUtils.closeIO(is);
            }
        }
    
        /**
         * 获取bitmap
         *
         * @param filePath 文件路径
         * @return bitmap
         */
        public static Bitmap getBitmap(String filePath) {
            if (StringUtils.isSpace(filePath)) return null;
            return BitmapFactory.decodeFile(filePath);
        }
    
        /**
         * 获取bitmap
         *
         * @param filePath  文件路径
         * @param maxWidth  最大宽度
         * @param maxHeight 最大高度
         * @return bitmap
         */
        public static Bitmap getBitmap(String filePath, int maxWidth, int maxHeight) {
            if (StringUtils.isSpace(filePath)) return null;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(filePath, options);
            options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeFile(filePath, options);
        }
    
        /**
         * 获取bitmap
         *
         * @param is 输入流
         * @return bitmap
         */
        public static Bitmap getBitmap(InputStream is) {
            if (is == null) return null;
            return BitmapFactory.decodeStream(is);
        }
    
        /**
         * 获取bitmap
         *
         * @param is        输入流
         * @param maxWidth  最大宽度
         * @param maxHeight 最大高度
         * @return bitmap
         */
        public static Bitmap getBitmap(InputStream is, int maxWidth, int maxHeight) {
            if (is == null) return null;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(is, null, options);
            options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeStream(is, null, options);
        }
    
        /**
         * 获取bitmap
         *
         * @param data   数据
         * @param offset 偏移量
         * @return bitmap
         */
        public static Bitmap getBitmap(byte[] data, int offset) {
            if (data.length == 0) return null;
            return BitmapFactory.decodeByteArray(data, offset, data.length);
        }
    
        /**
         * 获取bitmap
         *
         * @param data      数据
         * @param offset    偏移量
         * @param maxWidth  最大宽度
         * @param maxHeight 最大高度
         * @return bitmap
         */
        public static Bitmap getBitmap(byte[] data, int offset, int maxWidth, int maxHeight) {
            if (data.length == 0) return null;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeByteArray(data, offset, data.length, options);
            options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeByteArray(data, offset, data.length, options);
        }
    
        /**
         * 获取bitmap
         *
         * @param res 资源对象
         * @param id  资源id
         * @return bitmap
         */
        public static Bitmap getBitmap(Resources res, int id) {
            if (res == null) return null;
            return BitmapFactory.decodeResource(res, id);
        }
    
        /**
         * 获取bitmap
         *
         * @param res       资源对象
         * @param id        资源id
         * @param maxWidth  最大宽度
         * @param maxHeight 最大高度
         * @return bitmap
         */
        public static Bitmap getBitmap(Resources res, int id, int maxWidth, int maxHeight) {
            if (res == null) return null;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeResource(res, id, options);
            options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeResource(res, id, options);
        }
    
        /**
         * 获取bitmap
         *
         * @param fd 文件描述
         * @return bitmap
         */
        public static Bitmap getBitmap(FileDescriptor fd) {
            if (fd == null) return null;
            return BitmapFactory.decodeFileDescriptor(fd);
        }
    
        /**
         * 获取bitmap
         *
         * @param fd        文件描述
         * @param maxWidth  最大宽度
         * @param maxHeight 最大高度
         * @return bitmap
         */
        public static Bitmap getBitmap(FileDescriptor fd, int maxWidth, int maxHeight) {
            if (fd == null) return null;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFileDescriptor(fd, null, options);
            options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeFileDescriptor(fd, null, options);
        }
    
        /**
         * 缩放图片
         *
         * @param src       源图片
         * @param newWidth  新宽度
         * @param newHeight 新高度
         * @return 缩放后的图片
         */
        public static Bitmap scale(Bitmap src, int newWidth, int newHeight) {
            return scale(src, newWidth, newHeight, false);
        }
    
        /**
         * 缩放图片
         *
         * @param src       源图片
         * @param newWidth  新宽度
         * @param newHeight 新高度
         * @param recycle   是否回收
         * @return 缩放后的图片
         */
        public static Bitmap scale(Bitmap src, int newWidth, int newHeight, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            Bitmap ret = Bitmap.createScaledBitmap(src, newWidth, newHeight, true);
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 缩放图片
         *
         * @param src         源图片
         * @param scaleWidth  缩放宽度倍数
         * @param scaleHeight 缩放高度倍数
         * @return 缩放后的图片
         */
        public static Bitmap scale(Bitmap src, float scaleWidth, float scaleHeight) {
            return scale(src, scaleWidth, scaleHeight, false);
        }
    
        /**
         * 缩放图片
         *
         * @param src         源图片
         * @param scaleWidth  缩放宽度倍数
         * @param scaleHeight 缩放高度倍数
         * @param recycle     是否回收
         * @return 缩放后的图片
         */
        public static Bitmap scale(Bitmap src, float scaleWidth, float scaleHeight, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            Matrix matrix = new Matrix();
            matrix.setScale(scaleWidth, scaleHeight);
            Bitmap ret = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 裁剪图片
         *
         * @param src    源图片
         * @param x      开始坐标x
         * @param y      开始坐标y
         * @param width  裁剪宽度
         * @param height 裁剪高度
         * @return 裁剪后的图片
         */
        public static Bitmap clip(Bitmap src, int x, int y, int width, int height) {
            return clip(src, x, y, width, height, false);
        }
    
        /**
         * 裁剪图片
         *
         * @param src     源图片
         * @param x       开始坐标x
         * @param y       开始坐标y
         * @param width   裁剪宽度
         * @param height  裁剪高度
         * @param recycle 是否回收
         * @return 裁剪后的图片
         */
        public static Bitmap clip(Bitmap src, int x, int y, int width, int height, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            Bitmap ret = Bitmap.createBitmap(src, x, y, width, height);
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 倾斜图片
         *
         * @param src 源图片
         * @param kx  倾斜因子x
         * @param ky  倾斜因子y
         * @return 倾斜后的图片
         */
        public static Bitmap skew(Bitmap src, float kx, float ky) {
            return skew(src, kx, ky, 0, 0, false);
        }
    
        /**
         * 倾斜图片
         *
         * @param src     源图片
         * @param kx      倾斜因子x
         * @param ky      倾斜因子y
         * @param recycle 是否回收
         * @return 倾斜后的图片
         */
        public static Bitmap skew(Bitmap src, float kx, float ky, boolean recycle) {
            return skew(src, kx, ky, 0, 0, recycle);
        }
    
        /**
         * 倾斜图片
         *
         * @param src 源图片
         * @param kx  倾斜因子x
         * @param ky  倾斜因子y
         * @param px  平移因子x
         * @param py  平移因子y
         * @return 倾斜后的图片
         */
        public static Bitmap skew(Bitmap src, float kx, float ky, float px, float py) {
            return skew(src, kx, ky, px, py, false);
        }
    
        /**
         * 倾斜图片
         *
         * @param src     源图片
         * @param kx      倾斜因子x
         * @param ky      倾斜因子y
         * @param px      平移因子x
         * @param py      平移因子y
         * @param recycle 是否回收
         * @return 倾斜后的图片
         */
        public static Bitmap skew(Bitmap src, float kx, float ky, float px, float py, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            Matrix matrix = new Matrix();
            matrix.setSkew(kx, ky, px, py);
            Bitmap ret = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 旋转图片
         *
         * @param src     源图片
         * @param degrees 旋转角度
         * @param px      旋转点横坐标
         * @param py      旋转点纵坐标
         * @return 旋转后的图片
         */
        public static Bitmap rotate(Bitmap src, int degrees, float px, float py) {
            return rotate(src, degrees, px, py, false);
        }
    
        /**
         * 旋转图片
         *
         * @param src     源图片
         * @param degrees 旋转角度
         * @param px      旋转点横坐标
         * @param py      旋转点纵坐标
         * @param recycle 是否回收
         * @return 旋转后的图片
         */
        public static Bitmap rotate(Bitmap src, int degrees, float px, float py, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            if (degrees == 0) return src;
            Matrix matrix = new Matrix();
            matrix.setRotate(degrees, px, py);
            Bitmap ret = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 获取图片旋转角度
         *
         * @param filePath 文件路径
         * @return 旋转角度
         */
        public static int getRotateDegree(String filePath) {
            int degree = 0;
            try {
                ExifInterface exifInterface = new ExifInterface(filePath);
                int orientation = exifInterface.getAttributeInt(
                        ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_NORMAL);
                switch (orientation) {
                    default:
                    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 src 源图片
         * @return 圆形图片
         */
        public static Bitmap toRound(Bitmap src) {
            return toRound(src, false);
        }
    
        /**
         * 转为圆形图片
         *
         * @param src     源图片
         * @param recycle 是否回收
         * @return 圆形图片
         */
        public static Bitmap toRound(Bitmap src, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            int width = src.getWidth();
            int height = src.getHeight();
            int radius = Math.min(width, height) >> 1;
            Bitmap ret = Bitmap.createBitmap(width, height, src.getConfig());
            Paint paint = new Paint();
            Canvas canvas = new Canvas(ret);
            Rect rect = new Rect(0, 0, width, height);
            paint.setAntiAlias(true);
            canvas.drawARGB(0, 0, 0, 0);
            canvas.drawCircle(width >> 1, height >> 1, radius, paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(src, rect, rect, paint);
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 转为圆角图片
         *
         * @param src    源图片
         * @param radius 圆角的度数
         * @return 圆角图片
         */
        public static Bitmap toRoundCorner(Bitmap src, float radius) {
            return toRoundCorner(src, radius, false);
        }
    
        /**
         * 转为圆角图片
         *
         * @param src     源图片
         * @param radius  圆角的度数
         * @param recycle 是否回收
         * @return 圆角图片
         */
        public static Bitmap toRoundCorner(Bitmap src, float radius, boolean recycle) {
            if (null == src) return null;
            int width = src.getWidth();
            int height = src.getHeight();
            Bitmap ret = Bitmap.createBitmap(width, height, src.getConfig());
            Paint paint = new Paint();
            Canvas canvas = new Canvas(ret);
            Rect rect = new Rect(0, 0, width, height);
            paint.setAntiAlias(true);
            canvas.drawRoundRect(new RectF(rect), radius, radius, paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(src, rect, rect, paint);
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 快速模糊
         * <p>先缩小原图,对小图进行模糊,再放大回原先尺寸</p>
         *
         * @param src    源图片
         * @param scale  缩放比例(0...1)
         * @param radius 模糊半径
         * @return 模糊后的图片
         */
        public static Bitmap fastBlur(Bitmap src,
                                      @FloatRange(from = 0, to = 1, fromInclusive = false) float scale,
                                      @FloatRange(from = 0, to = 25, fromInclusive = false) float radius) {
            return fastBlur(src, scale, radius, false);
        }
    
        /**
         * 快速模糊图片
         * <p>先缩小原图,对小图进行模糊,再放大回原先尺寸</p>
         *
         * @param src     源图片
         * @param scale   缩放比例(0...1)
         * @param radius  模糊半径(0...25)
         * @param recycle 是否回收
         * @return 模糊后的图片
         */
        public static Bitmap fastBlur(Bitmap src,
                                      @FloatRange(from = 0, to = 1, fromInclusive = false) float scale,
                                      @FloatRange(from = 0, to = 25, fromInclusive = false) float radius,
                                      boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            int width = src.getWidth();
            int height = src.getHeight();
            int scaleWidth = (int) (width * scale + 0.5f);
            int scaleHeight = (int) (height * scale + 0.5f);
            if (scaleWidth == 0 || scaleHeight == 0) return null;
            Bitmap scaleBitmap = Bitmap.createScaledBitmap(src, scaleWidth, scaleHeight, true);
            Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
            Canvas canvas = new Canvas();
            PorterDuffColorFilter filter = new PorterDuffColorFilter(
                    Color.TRANSPARENT, PorterDuff.Mode.SRC_ATOP);
            paint.setColorFilter(filter);
            canvas.scale(scale, scale);
            canvas.drawBitmap(scaleBitmap, 0, 0, paint);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                scaleBitmap = renderScriptBlur(Utils.getContext(), scaleBitmap, radius);
            } else {
                scaleBitmap = stackBlur(scaleBitmap, (int) radius, recycle);
            }
            if (scale == 1) return scaleBitmap;
            Bitmap ret = Bitmap.createScaledBitmap(scaleBitmap, width, height, true);
            if (scaleBitmap != null && !scaleBitmap.isRecycled()) scaleBitmap.recycle();
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * renderScript模糊图片
         * <p>API大于17</p>
         *
         * @param context 上下文
         * @param src     源图片
         * @param radius  模糊半径(0...25)
         * @return 模糊后的图片
         */
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
        public static Bitmap renderScriptBlur(Context context, Bitmap src, @FloatRange(from = 0, to = 25, fromInclusive = false) float radius) {
            if (isEmptyBitmap(src)) return null;
            RenderScript rs = null;
            try {
                rs = RenderScript.create(context);
                rs.setMessageHandler(new RenderScript.RSMessageHandler());
                Allocation input = Allocation.createFromBitmap(rs, src, Allocation.MipmapControl.MIPMAP_NONE, Allocation
                        .USAGE_SCRIPT);
                Allocation output = Allocation.createTyped(rs, input.getType());
                ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
                blurScript.setInput(input);
                blurScript.setRadius(radius);
                blurScript.forEach(output);
                output.copyTo(src);
            } finally {
                if (rs != null) {
                    rs.destroy();
                }
            }
            return src;
        }
    
        /**
         * stack模糊图片
         *
         * @param src     源图片
         * @param radius  模糊半径
         * @param recycle 是否回收
         * @return stack模糊后的图片
         */
        public static Bitmap stackBlur(Bitmap src, int radius, boolean recycle) {
            Bitmap ret;
            if (recycle) {
                ret = src;
            } else {
                ret = src.copy(src.getConfig(), true);
            }
    
            if (radius < 1) {
                return null;
            }
    
            int w = ret.getWidth();
            int h = ret.getHeight();
    
            int[] pix = new int[w * h];
            ret.getPixels(pix, 0, w, 0, 0, w, h);
    
            int wm = w - 1;
            int hm = h - 1;
            int wh = w * h;
            int div = radius + radius + 1;
    
            int r[] = new int[wh];
            int g[] = new int[wh];
            int b[] = new int[wh];
            int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
            int vmin[] = new int[Math.max(w, h)];
    
            int divsum = (div + 1) >> 1;
            divsum *= divsum;
            int dv[] = new int[256 * divsum];
            for (i = 0; i < 256 * divsum; i++) {
                dv[i] = (i / divsum);
            }
    
            yw = yi = 0;
    
            int[][] stack = new int[div][3];
            int stackpointer;
            int stackstart;
            int[] sir;
            int rbs;
            int r1 = radius + 1;
            int routsum, goutsum, boutsum;
            int rinsum, ginsum, binsum;
    
            for (y = 0; y < h; y++) {
                rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
                for (i = -radius; i <= radius; i++) {
                    p = pix[yi + Math.min(wm, Math.max(i, 0))];
                    sir = stack[i + radius];
                    sir[0] = (p & 0xff0000) >> 16;
                    sir[1] = (p & 0x00ff00) >> 8;
                    sir[2] = (p & 0x0000ff);
                    rbs = r1 - Math.abs(i);
                    rsum += sir[0] * rbs;
                    gsum += sir[1] * rbs;
                    bsum += sir[2] * rbs;
                    if (i > 0) {
                        rinsum += sir[0];
                        ginsum += sir[1];
                        binsum += sir[2];
                    } else {
                        routsum += sir[0];
                        goutsum += sir[1];
                        boutsum += sir[2];
                    }
                }
                stackpointer = radius;
    
                for (x = 0; x < w; x++) {
    
                    r[yi] = dv[rsum];
                    g[yi] = dv[gsum];
                    b[yi] = dv[bsum];
    
                    rsum -= routsum;
                    gsum -= goutsum;
                    bsum -= boutsum;
    
                    stackstart = stackpointer - radius + div;
                    sir = stack[stackstart % div];
    
                    routsum -= sir[0];
                    goutsum -= sir[1];
                    boutsum -= sir[2];
    
                    if (y == 0) {
                        vmin[x] = Math.min(x + radius + 1, wm);
                    }
                    p = pix[yw + vmin[x]];
    
                    sir[0] = (p & 0xff0000) >> 16;
                    sir[1] = (p & 0x00ff00) >> 8;
                    sir[2] = (p & 0x0000ff);
    
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
    
                    rsum += rinsum;
                    gsum += ginsum;
                    bsum += binsum;
    
                    stackpointer = (stackpointer + 1) % div;
                    sir = stack[(stackpointer) % div];
    
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
    
                    rinsum -= sir[0];
                    ginsum -= sir[1];
                    binsum -= sir[2];
    
                    yi++;
                }
                yw += w;
            }
            for (x = 0; x < w; x++) {
                rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
                yp = -radius * w;
                for (i = -radius; i <= radius; i++) {
                    yi = Math.max(0, yp) + x;
    
                    sir = stack[i + radius];
    
                    sir[0] = r[yi];
                    sir[1] = g[yi];
                    sir[2] = b[yi];
    
                    rbs = r1 - Math.abs(i);
    
                    rsum += r[yi] * rbs;
                    gsum += g[yi] * rbs;
                    bsum += b[yi] * rbs;
    
                    if (i > 0) {
                        rinsum += sir[0];
                        ginsum += sir[1];
                        binsum += sir[2];
                    } else {
                        routsum += sir[0];
                        goutsum += sir[1];
                        boutsum += sir[2];
                    }
    
                    if (i < hm) {
                        yp += w;
                    }
                }
                yi = x;
                stackpointer = radius;
                for (y = 0; y < h; y++) {
                    // Preserve alpha channel: ( 0xff000000 & pix[yi] )
                    pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
    
                    rsum -= routsum;
                    gsum -= goutsum;
                    bsum -= boutsum;
    
                    stackstart = stackpointer - radius + div;
                    sir = stack[stackstart % div];
    
                    routsum -= sir[0];
                    goutsum -= sir[1];
                    boutsum -= sir[2];
    
                    if (x == 0) {
                        vmin[y] = Math.min(y + r1, hm) * w;
                    }
                    p = x + vmin[y];
    
                    sir[0] = r[p];
                    sir[1] = g[p];
                    sir[2] = b[p];
    
                    rinsum += sir[0];
                    ginsum += sir[1];
                    binsum += sir[2];
    
                    rsum += rinsum;
                    gsum += ginsum;
                    bsum += binsum;
    
                    stackpointer = (stackpointer + 1) % div;
                    sir = stack[stackpointer];
    
                    routsum += sir[0];
                    goutsum += sir[1];
                    boutsum += sir[2];
    
                    rinsum -= sir[0];
                    ginsum -= sir[1];
                    binsum -= sir[2];
    
                    yi += w;
                }
            }
            ret.setPixels(pix, 0, w, 0, 0, w, h);
            return ret;
        }
    
        /**
         * 添加颜色边框
         *
         * @param src         源图片
         * @param borderWidth 边框宽度
         * @param color       边框的颜色值
         * @return 带颜色边框图
         */
        public static Bitmap addFrame(Bitmap src, int borderWidth, int color) {
            return addFrame(src, borderWidth, color, false);
        }
    
        /**
         * 添加颜色边框
         *
         * @param src         源图片
         * @param borderWidth 边框宽度
         * @param color       边框的颜色值
         * @param recycle     是否回收
         * @return 带颜色边框图
         */
        public static Bitmap addFrame(Bitmap src, int borderWidth, int color, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            int doubleBorder = borderWidth << 1;
            int newWidth = src.getWidth() + doubleBorder;
            int newHeight = src.getHeight() + doubleBorder;
            Bitmap ret = Bitmap.createBitmap(newWidth, newHeight, src.getConfig());
            Canvas canvas = new Canvas(ret);
            Rect rect = new Rect(0, 0, newWidth, newHeight);
            Paint paint = new Paint();
            paint.setColor(color);
            paint.setStyle(Paint.Style.STROKE);
            // setStrokeWidth是居中画的,所以要两倍的宽度才能画,否则有一半的宽度是空的
            paint.setStrokeWidth(doubleBorder);
            canvas.drawRect(rect, paint);
            canvas.drawBitmap(src, borderWidth, borderWidth, null);
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 添加倒影
         *
         * @param src              源图片的
         * @param reflectionHeight 倒影高度
         * @return 带倒影图片
         */
        public static Bitmap addReflection(Bitmap src, int reflectionHeight) {
            return addReflection(src, reflectionHeight, false);
        }
    
        /**
         * 添加倒影
         *
         * @param src              源图片的
         * @param reflectionHeight 倒影高度
         * @param recycle          是否回收
         * @return 带倒影图片
         */
        public static Bitmap addReflection(Bitmap src, int reflectionHeight, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            // 原图与倒影之间的间距
            final int REFLECTION_GAP = 0;
            int srcWidth = src.getWidth();
            int srcHeight = src.getHeight();
            Matrix matrix = new Matrix();
            matrix.preScale(1, -1);
            Bitmap reflectionBitmap = Bitmap.createBitmap(src, 0, srcHeight - reflectionHeight,
                    srcWidth, reflectionHeight, matrix, false);
            Bitmap ret = Bitmap.createBitmap(srcWidth, srcHeight + reflectionHeight, src.getConfig());
            Canvas canvas = new Canvas(ret);
            canvas.drawBitmap(src, 0, 0, null);
            canvas.drawBitmap(reflectionBitmap, 0, srcHeight + REFLECTION_GAP, null);
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            LinearGradient shader = new LinearGradient(0, srcHeight,
                    0, ret.getHeight() + REFLECTION_GAP,
                    0x70FFFFFF, 0x00FFFFFF, Shader.TileMode.MIRROR);
            paint.setShader(shader);
            paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_IN));
            canvas.drawRect(0, srcHeight + REFLECTION_GAP,
                    srcWidth, ret.getHeight(), paint);
            if (!reflectionBitmap.isRecycled()) reflectionBitmap.recycle();
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 添加文字水印
         *
         * @param src      源图片
         * @param content  水印文本
         * @param textSize 水印字体大小
         * @param color    水印字体颜色
         * @param x        起始坐标x
         * @param y        起始坐标y
         * @return 带有文字水印的图片
         */
        public static Bitmap addTextWatermark(Bitmap src, String content, int textSize, int color, float x,
                                              float y) {
            return addTextWatermark(src, content, textSize, color, x, y, false);
        }
    
        /**
         * 添加文字水印
         *
         * @param src      源图片
         * @param content  水印文本
         * @param textSize 水印字体大小
         * @param color    水印字体颜色
         * @param x        起始坐标x
         * @param y        起始坐标y
         * @param recycle  是否回收
         * @return 带有文字水印的图片
         */
        public static Bitmap addTextWatermark(Bitmap src, String content, float textSize, int color, float x,
                                              float y, boolean recycle) {
            if (isEmptyBitmap(src) || content == null) return null;
            Bitmap ret = src.copy(src.getConfig(), true);
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            Canvas canvas = new Canvas(ret);
            paint.setColor(color);
            paint.setTextSize(textSize);
            Rect bounds = new Rect();
            paint.getTextBounds(content, 0, content.length(), bounds);
            canvas.drawText(content, x, y + textSize, paint);
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 添加图片水印
         *
         * @param src       源图片
         * @param watermark 图片水印
         * @param x         起始坐标x
         * @param y         起始坐标y
         * @param alpha     透明度
         * @return 带有图片水印的图片
         */
        public static Bitmap addImageWatermark(Bitmap src, Bitmap watermark, int x, int y, int alpha) {
            return addImageWatermark(src, watermark, x, y, alpha, false);
        }
    
        /**
         * 添加图片水印
         *
         * @param src       源图片
         * @param watermark 图片水印
         * @param x         起始坐标x
         * @param y         起始坐标y
         * @param alpha     透明度
         * @param recycle   是否回收
         * @return 带有图片水印的图片
         */
        public static Bitmap addImageWatermark(Bitmap src, Bitmap watermark, int x, int y, int alpha, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            Bitmap ret = src.copy(src.getConfig(), true);
            if (!isEmptyBitmap(watermark)) {
                Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
                Canvas canvas = new Canvas(ret);
                paint.setAlpha(alpha);
                canvas.drawBitmap(watermark, x, y, paint);
            }
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 转为alpha位图
         *
         * @param src 源图片
         * @return alpha位图
         */
        public static Bitmap toAlpha(Bitmap src) {
            return toAlpha(src, false);
        }
    
        /**
         * 转为alpha位图
         *
         * @param src     源图片
         * @param recycle 是否回收
         * @return alpha位图
         */
        public static Bitmap toAlpha(Bitmap src, Boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            Bitmap ret = src.extractAlpha();
            if (recycle && !src.isRecycled()) src.recycle();
            return ret;
        }
    
        /**
         * 转为灰度图片
         *
         * @param src 源图片
         * @return 灰度图
         */
        public static Bitmap toGray(Bitmap src) {
            return toGray(src, false);
        }
    
        /**
         * 转为灰度图片
         *
         * @param src     源图片
         * @param recycle 是否回收
         * @return 灰度图
         */
        public static Bitmap toGray(Bitmap src, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            Bitmap grayBitmap = Bitmap.createBitmap(src.getWidth(),
                    src.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(grayBitmap);
            Paint paint = new Paint();
            ColorMatrix colorMatrix = new ColorMatrix();
            colorMatrix.setSaturation(0);
            ColorMatrixColorFilter colorMatrixColorFilter = new ColorMatrixColorFilter(colorMatrix);
            paint.setColorFilter(colorMatrixColorFilter);
            canvas.drawBitmap(src, 0, 0, paint);
            if (recycle && !src.isRecycled()) src.recycle();
            return grayBitmap;
        }
    
        /**
         * 保存图片
         *
         * @param src      源图片
         * @param filePath 要保存到的文件路径
         * @param format   格式
         * @return {@code true}: 成功<br>{@code false}: 失败
         */
        public static boolean save(Bitmap src, String filePath, CompressFormat format) {
            return save(src, FileUtils.getFileByPath(filePath), format, false);
        }
    
        /**
         * 保存图片
         *
         * @param src    源图片
         * @param file   要保存到的文件
         * @param format 格式
         * @return {@code true}: 成功<br>{@code false}: 失败
         */
        public static boolean save(Bitmap src, File file, CompressFormat format) {
            return save(src, file, format, false);
        }
    
        /**
         * 保存图片
         *
         * @param src      源图片
         * @param filePath 要保存到的文件路径
         * @param format   格式
         * @param recycle  是否回收
         * @return {@code true}: 成功<br>{@code false}: 失败
         */
        public static boolean save(Bitmap src, String filePath, CompressFormat format, boolean recycle) {
            return save(src, FileUtils.getFileByPath(filePath), format, recycle);
        }
    
        /**
         * 保存图片
         *
         * @param src     源图片
         * @param file    要保存到的文件
         * @param format  格式
         * @param recycle 是否回收
         * @return {@code true}: 成功<br>{@code false}: 失败
         */
        public static boolean save(Bitmap src, File file, CompressFormat format, boolean recycle) {
            if (isEmptyBitmap(src) || !FileUtils.createOrExistsFile(file)) return false;
            System.out.println(src.getWidth() + ", " + src.getHeight());
            OutputStream os = null;
            boolean ret = false;
            try {
                os = new BufferedOutputStream(new FileOutputStream(file));
                ret = src.compress(format, 100, os);
                if (recycle && !src.isRecycled()) src.recycle();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                CloseUtils.closeIO(os);
            }
            return ret;
        }
    
        /**
         * 根据文件名判断文件是否为图片
         *
         * @param file  文件
         * @return {@code true}: 是<br>{@code false}: 否
         */
        public static boolean isImage(File file) {
            return file != null && isImage(file.getPath());
        }
    
        /**
         * 根据文件名判断文件是否为图片
         *
         * @param filePath  文件路径
         * @return {@code true}: 是<br>{@code false}: 否
         */
        public static boolean isImage(String filePath) {
            String path = filePath.toUpperCase();
            return path.endsWith(".PNG") || path.endsWith(".JPG")
                    || path.endsWith(".JPEG") || path.endsWith(".BMP")
                    || path.endsWith(".GIF");
        }
    
        /**
         * 获取图片类型
         *
         * @param filePath 文件路径
         * @return 图片类型
         */
        public static String getImageType(String filePath) {
            return getImageType(FileUtils.getFileByPath(filePath));
        }
    
        /**
         * 获取图片类型
         *
         * @param file 文件
         * @return 图片类型
         */
        public static String getImageType(File file) {
            if (file == null) return null;
            InputStream is = null;
            try {
                is = new FileInputStream(file);
                return getImageType(is);
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            } finally {
                CloseUtils.closeIO(is);
            }
        }
    
        /**
         * 流获取图片类型
         *
         * @param is 图片输入流
         * @return 图片类型
         */
        public static String getImageType(InputStream is) {
            if (is == null) return null;
            try {
                byte[] bytes = new byte[8];
                return is.read(bytes, 0, 8) != -1 ? getImageType(bytes) : null;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 获取图片类型
         *
         * @param bytes bitmap的前8字节
         * @return 图片类型
         */
        public static String getImageType(byte[] bytes) {
            if (isJPEG(bytes)) return "JPEG";
            if (isGIF(bytes)) return "GIF";
            if (isPNG(bytes)) return "PNG";
            if (isBMP(bytes)) return "BMP";
            return null;
        }
    
        private static boolean isJPEG(byte[] b) {
            return b.length >= 2
                    && (b[0] == (byte) 0xFF) && (b[1] == (byte) 0xD8);
        }
    
        private static boolean isGIF(byte[] b) {
            return b.length >= 6
                    && b[0] == 'G' && b[1] == 'I'
                    && b[2] == 'F' && b[3] == '8'
                    && (b[4] == '7' || b[4] == '9') && b[5] == 'a';
        }
    
        private static boolean isPNG(byte[] b) {
            return b.length >= 8
                    && (b[0] == (byte) 137 && b[1] == (byte) 80
                    && b[2] == (byte) 78 && b[3] == (byte) 71
                    && b[4] == (byte) 13 && b[5] == (byte) 10
                    && b[6] == (byte) 26 && b[7] == (byte) 10);
        }
    
        private static boolean isBMP(byte[] b) {
            return b.length >= 2
                    && (b[0] == 0x42) && (b[1] == 0x4d);
        }
    
        /**
         * 判断bitmap对象是否为空
         *
         * @param src 源图片
         * @return {@code true}: 是<br>{@code false}: 否
         */
        private static boolean isEmptyBitmap(Bitmap src) {
            return src == null || src.getWidth() == 0 || src.getHeight() == 0;
        }
    
        /******************************~~~~~~~~~ 下方和压缩有关 ~~~~~~~~~******************************/
    
        /**
         * 按缩放压缩
         *
         * @param src       源图片
         * @param newWidth  新宽度
         * @param newHeight 新高度
         * @return 缩放压缩后的图片
         */
        public static Bitmap compressByScale(Bitmap src, int newWidth, int newHeight) {
            return scale(src, newWidth, newHeight, false);
        }
    
        /**
         * 按缩放压缩
         *
         * @param src       源图片
         * @param newWidth  新宽度
         * @param newHeight 新高度
         * @param recycle   是否回收
         * @return 缩放压缩后的图片
         */
        public static Bitmap compressByScale(Bitmap src, int newWidth, int newHeight, boolean recycle) {
            return scale(src, newWidth, newHeight, recycle);
        }
    
        /**
         * 按缩放压缩
         *
         * @param src         源图片
         * @param scaleWidth  缩放宽度倍数
         * @param scaleHeight 缩放高度倍数
         * @return 缩放压缩后的图片
         */
        public static Bitmap compressByScale(Bitmap src, float scaleWidth, float scaleHeight) {
            return scale(src, scaleWidth, scaleHeight, false);
        }
    
        /**
         * 按缩放压缩
         *
         * @param src         源图片
         * @param scaleWidth  缩放宽度倍数
         * @param scaleHeight 缩放高度倍数
         * @param recycle     是否回收
         * @return 缩放压缩后的图片
         */
        public static Bitmap compressByScale(Bitmap src, float scaleWidth, float scaleHeight, boolean recycle) {
            return scale(src, scaleWidth, scaleHeight, recycle);
        }
    
        /**
         * 按质量压缩
         *
         * @param src     源图片
         * @param quality 质量
         * @return 质量压缩后的图片
         */
        public static Bitmap compressByQuality(Bitmap src, @IntRange(from = 0, to = 100) int quality) {
            return compressByQuality(src, quality, false);
        }
    
        /**
         * 按质量压缩
         *
         * @param src     源图片
         * @param quality 质量
         * @param recycle 是否回收
         * @return 质量压缩后的图片
         */
        public static Bitmap compressByQuality(Bitmap src, @IntRange(from = 0, to = 100) int quality, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            src.compress(Bitmap.CompressFormat.JPEG, quality, baos);
            byte[] bytes = baos.toByteArray();
            if (recycle && !src.isRecycled()) src.recycle();
            return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        }
    
        /**
         * 按质量压缩
         *
         * @param src         源图片
         * @param maxByteSize 允许最大值字节数
         * @return 质量压缩压缩过的图片
         */
        public static Bitmap compressByQuality(Bitmap src, long maxByteSize) {
            return compressByQuality(src, maxByteSize, false);
        }
    
        /**
         * 按质量压缩
         *
         * @param src         源图片
         * @param maxByteSize 允许最大值字节数
         * @param recycle     是否回收
         * @return 质量压缩压缩过的图片
         */
        public static Bitmap compressByQuality(Bitmap src, long maxByteSize, boolean recycle) {
            if (isEmptyBitmap(src) || maxByteSize <= 0) return null;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int quality = 100;
            src.compress(CompressFormat.JPEG, quality, baos);
            while (baos.toByteArray().length > maxByteSize && quality > 0) {
                baos.reset();
                src.compress(CompressFormat.JPEG, quality -= 5, baos);
            }
            if (quality < 0) return null;
            byte[] bytes = baos.toByteArray();
            if (recycle && !src.isRecycled()) src.recycle();
            return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        }
    
        /**
         * 按采样大小压缩
         *
         * @param src        源图片
         * @param sampleSize 采样率大小
         * @return 按采样率压缩后的图片
         */
        public static Bitmap compressBySampleSize(Bitmap src, int sampleSize) {
            return compressBySampleSize(src, sampleSize, false);
        }
    
        /**
         * 按采样大小压缩
         *
         * @param src        源图片
         * @param sampleSize 采样率大小
         * @param recycle    是否回收
         * @return 按采样率压缩后的图片
         */
        public static Bitmap compressBySampleSize(Bitmap src, int sampleSize, boolean recycle) {
            if (isEmptyBitmap(src)) return null;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = sampleSize;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            src.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            byte[] bytes = baos.toByteArray();
            if (recycle && !src.isRecycled()) src.recycle();
            return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
        }
    }
    View Code

    http://www.jianshu.com/p/72494773aace

    QRcode

    package com.summer.common.utils.img;
    
    import java.awt.AlphaComposite;
    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.Transparency;
    import java.awt.geom.Ellipse2D;
    import java.awt.geom.RoundRectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Paths;
    import java.util.HashMap;
    import java.util.Hashtable;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.WriterException;
    import com.google.zxing.client.j2se.MatrixToImageConfig;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    public class QRUtils {
    
        public static void main(String[] args) throws IOException, WriterException {
            String format = "jpg";
            int QRCODE_SIZE = 1000;
            
            MatrixToImageWriter.toBufferedImage(encodePDF17("haha", QRCODE_SIZE));
    //        writeQR("haha", 102, "C:\haha.jpg", format);
    //        BufferedImage ImageOne = getQRImage("houpin.1688.com", QRCODE_SIZE);
            MatrixToImageWriter.writeToPath(encodePDF17("haha", QRCODE_SIZE), format, Paths.get("C:\haha.jpg"));
    
          //对第二张图片做相同的处理
    //           File fileTwo = new File("c:\1.jpg");
    //           BufferedImage ImageTwo = ImageIO.read(fileTwo);
    //           BufferedImage ImageNew = createQRImageWithCirclePortrait(ImageOne, ImageTwo);
    //         ImageIO.write(ImageNew, format, new File("c://123-A.jpg"));
    //         ImageIO.write( createQRImageWithSquarePortrait(ImageOne, ImageTwo), format, new File("c://123-B.jpg"));
    //         ImageIO.write( createQRCodeBitmapWithRoundRectanglePortrait(ImageOne, ImageTwo), format, new File("c://123-C.jpg"));
        }
        
        // 计算边框比例
        private static final int BORDER_LEMON = 30;
        
        /**
         * 如果小于1像素,返回1px
         * @param size
         * @return
         */
        private static int calBorderPix(int size) {
            int border = size /BORDER_LEMON;
            return border > 1 ? border : 1;
        }
        
        /**
         * 把source拷贝到RGB BufferedImage
         * @param source
         * @return
         */
        private static BufferedImage copyToRGBImage(BufferedImage source) {
            int width = source.getWidth(), height = source.getWidth();
            BufferedImage imageNew = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            // 从QR中读取RGB
            int[] qrImageArray = new int[width * height];
            qrImageArray = source.getRGB(0,0,width,height,qrImageArray,0,width);
            // QR写入
            imageNew.setRGB(0, 0, width, height, qrImageArray, 0, width);
            return imageNew;
        }
        
        /**
         * 为QR码添加头像,方形,带白相框
         * @param qr
         * @param portrait    头像
         * @return
         */
        public static BufferedImage createQRImageWithSquarePortrait(BufferedImage qr, BufferedImage portrait) {
            BufferedImage imageNew = copyToRGBImage(qr);
            // portrait
            int portraitWidth = portrait.getWidth(), portraitHeight = portrait.getHeight();
            // 框偏移
            int wBorder = calBorderPix(portraitWidth), hBorder = calBorderPix(portraitHeight);
            // 位置计算
            int left = (imageNew.getWidth()-portraitWidth) / 2, top = (imageNew.getHeight()-portraitHeight) / 2;
            // 先绘制白色背景
            // =
            for (int x=0; x<portraitWidth; x++) {
                for (int y=0; y<hBorder; y++) {
                    imageNew.setRGB(left+x, top+y, Color.white.getRGB());
                    imageNew.setRGB(left+x, top+y+portraitHeight - hBorder, Color.white.getRGB());
                }
            }
            //||
            for (int x=0; x<wBorder; x++) {
                for (int y=0; y<portraitHeight - hBorder; y++) {
                    imageNew.setRGB(left+x, top+y+hBorder, Color.white.getRGB());
                    imageNew.setRGB(left+x+portraitWidth-wBorder, top+y+hBorder, Color.white.getRGB());
                }
            }
            // 贴上头像
            addPortraitImg(imageNew, portrait, left + wBorder, top + hBorder, wBorder,hBorder,portraitWidth-2*wBorder,portraitHeight-2*hBorder);
            return imageNew;
        }
    
        private static void addPortraitImg(BufferedImage setImg,BufferedImage getImg,
                int sX, int sY,
                int gX, int gY,
                int gW, int gH
                ) {
            int[] portraitArray = new int[gW * gH];
            portraitArray = getImg.getRGB(gX, gY, gW, gH,portraitArray,0, gW);
            setImg.setRGB(sX, sY, gW, gH, portraitArray, 0, gW);
        }
    
        /**
         * 产生一个平滑,抗锯齿的Graphics2D
         * @param img
         * @return
         */
        private static Graphics2D createGraphics(BufferedImage img) {
            Graphics2D g2d = img.createGraphics();
               g2d.setStroke(new BasicStroke(1));
               // 使用 setRenderingHint 设置抗锯齿
               g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); 
               return g2d;
        }
        
        /**
         * 为QR码添加头像,圆形,带白相框
         * @param qr
         * @param portrait
         * @return
         * @throws IOException
         */
        public static BufferedImage createQRImageWithCirclePortrait(BufferedImage qr, BufferedImage portrait) throws IOException {
            BufferedImage imageNew = copyToRGBImage(qr);
            // portrait
            int portraitWidth = portrait.getWidth(), portraitHeight = portrait.getHeight();
            // 框偏移
            int wBorder = portraitWidth/ 30, hBorder = portraitHeight/ 30;
            // 位置计算
            int left = (imageNew.getWidth() - portraitWidth) / 2, top = (imageNew.getHeight() - portraitHeight) / 2;
            { // 先绘制白色背景
                BufferedImage circleBorder = new BufferedImage(portraitWidth + 2*wBorder, portraitWidth + 2*hBorder, BufferedImage.TYPE_INT_RGB);
                addPortraitImg(circleBorder, qr, 0, 0, left-wBorder,top-hBorder, portraitWidth+2*wBorder,portraitHeight+2*hBorder);
                Graphics2D g2d = createGraphics(circleBorder);
                g2d.setColor(Color.white);
                   g2d.fill( new Ellipse2D.Double(0,0,portraitWidth+ 2*wBorder,portraitHeight+ 2*hBorder));
                   g2d.dispose();
                addPortraitImg(imageNew, circleBorder, left-wBorder,top-hBorder, 0,0,portraitWidth+ 2*wBorder,portraitHeight+ 2*hBorder);
            }
            { // 在画
            BufferedImage circleImage = new BufferedImage(portraitWidth, portraitWidth, BufferedImage.TYPE_INT_RGB);
            addPortraitImg(circleImage, imageNew, 0, 0, left,top,portraitWidth,portraitHeight);
               Graphics2D g2d = createGraphics(circleImage);
               g2d.setClip(new Ellipse2D.Double(0,0,portraitWidth,portraitHeight));
               g2d.drawImage(portrait, 0, 0, null);
               g2d.dispose();
               addPortraitImg(imageNew, circleImage, left, top, 0,0,portraitWidth,portraitHeight);
            }
            return imageNew;
        }
        
        /**
         * 为QR码添加头像,圆角,带白相框
         * @param qr
         * @param portrait
         * @return
         * @throws IOException
         */
        public static BufferedImage createQRCodeBitmapWithRoundRectanglePortrait(BufferedImage qr, BufferedImage portrait) throws IOException {
            BufferedImage imageNew = copyToRGBImage(qr);
            // portrait
            int portraitWidth = portrait.getWidth(), portraitHeight = portrait.getHeight();
            // 框偏移
            int wBorder = portraitWidth/ 30, hBorder = portraitHeight/ 30;
            // 位置计算
            int left = (imageNew.getWidth() - portraitWidth) / 2, top = (imageNew.getHeight() - portraitHeight) / 2;
            { // 先绘制白色背景
                BufferedImage circleBorder = new BufferedImage(portraitWidth + 2*wBorder, portraitWidth + 2*hBorder, BufferedImage.TYPE_INT_RGB);
                addPortraitImg(circleBorder, qr, 0, 0, left-wBorder,top-hBorder, portraitWidth+2*wBorder,portraitHeight+2*hBorder);
                Graphics2D g2d = createGraphics(circleBorder);
                g2d.setColor(Color.white);
                   g2d.fill( new RoundRectangle2D.Double(0,0,portraitWidth+ 2*wBorder,portraitHeight+ 2*hBorder, wBorder *8 , hBorder *8));
                   g2d.dispose();
                addPortraitImg(imageNew, circleBorder, left-wBorder,top-hBorder, 0,0,portraitWidth+ 2*wBorder,portraitHeight+ 2*hBorder);
            }
            BufferedImage circleImage = new BufferedImage(portraitWidth, portraitWidth, BufferedImage.TYPE_INT_RGB);
            addPortraitImg(circleImage, imageNew, 0, 0, left,top,portraitWidth,portraitHeight);
               Graphics2D g2d = createGraphics(circleImage);
               g2d.setClip(new RoundRectangle2D.Double(0,0,portraitWidth,portraitHeight, wBorder *8 , hBorder *8));
               g2d.drawImage(portrait, 0, 0, null);
               g2d.dispose();
               addPortraitImg(imageNew, circleImage, left, top, 0,0,portraitWidth,portraitHeight);
            
            return imageNew;
        }
        
        
        /**
         * 返回透明的 <code>BufferedImage</code>.
         *
         * @param image image to be made transparent
         * @param transperancy value of the transparency
         * @return transparent <code>BufferedImage</code>
         */
        public static BufferedImage getTransparentImage(BufferedImage image, float transperancy) {
            // Create the image using the
            BufferedImage transparentImage = new BufferedImage(image.getWidth(), image.getHeight(), Transparency.TRANSLUCENT);
            // Get the images graphics.
            Graphics2D g = transparentImage.createGraphics();
            // Set the graphics composite to Alpha.
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, transperancy));
            // Draw the passed image into the new transparent image.
            g.drawImage(image, null, 0, 0);
            // Free all system resources.
            g.dispose();
            // Return the image
            return transparentImage;
        }
        
        /**
         * 写入路径的QR
         * @param content
         * @param sideLength
         * @param outfile
         * @param format
         * @throws IOException
         * @throws WriterException
         */
        public static void writeQR(String content, int sideLength, String outfile, String format) throws IOException, WriterException {
             BitMatrix matrix = encodeQR(content, sideLength);
             MatrixToImageWriter.writeToPath(matrix, format, Paths.get(outfile));
        }
        
        public static BufferedImage getQRImage(String content, int sideLength) throws WriterException {
            BitMatrix matrix = encodeQR(content, sideLength);
            return MatrixToImageWriter.toBufferedImage(matrix);
        }
        
        public static BufferedImage getQRImage(String content, int sideLength, MatrixToImageConfig config) throws WriterException {
            BitMatrix matrix = encodeQR(content, sideLength);
            return MatrixToImageWriter.toBufferedImage(matrix, config);
        }
        
        /**
         * 将BufferedImage转为bytes
         * @param image
         * @param format
         * @return
         * @throws IOException
         */
        public static byte[] convertBufferedImageToBytes(BufferedImage image, String format) throws IOException {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(image, format, out);
            return out.toByteArray();
        }
        
        /**
         * 将bytes转为BufferedImage
         * @param bytes
         * @return
         * @throws IOException
         */
        public static BufferedImage convertBytesToBufferedImage(byte[] bytes) throws IOException {
            ByteArrayInputStream in = new ByteArrayInputStream(bytes);    //作为输入流;
            return ImageIO.read(in);     //将in作为输入流,读取图片存入image中,而这里in可以为ByteArrayInputStream();
        }
        
        /**
         * QR编码
         * @param content
         * @param sideLength
         * @return
         * @throws WriterException
         */
        public static BitMatrix encodeQR(String content, int sideLength) throws WriterException {
            // 用于设置QR二维码参数
            Hashtable<EncodeHintType, Object> qrParam = new Hashtable<EncodeHintType, Object>();
            // 设置QR二维码的纠错级别——这里选择最高H级别
            qrParam.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            // 设置编码方式
            qrParam.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            MultiFormatWriter barcodeWriter = new MultiFormatWriter();
            // 编码内容,编码类型,生成图片宽度,生成图片高度,设置参数 
            BitMatrix matrix = barcodeWriter.encode(content, BarcodeFormat.QR_CODE, sideLength, sideLength, qrParam);
            return matrix;
        }
        
        /**
         * 
         * @param content
         * @param sideLength
         * @return
         * @throws WriterException
         */
        public static BitMatrix encodePDF17(String content, int sideLength) throws WriterException {
            // 用于设置QR二维码参数
            Hashtable<EncodeHintType, Object> qrParam = new Hashtable<EncodeHintType, Object>();
            // 设置QR二维码的纠错级别——这里选择最高H级别
            qrParam.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            // 设置编码方式
            qrParam.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            MultiFormatWriter barcodeWriter = new MultiFormatWriter();
            // 编码内容,编码类型,生成图片宽度,生成图片高度,设置参数 
            //BarcodeFormat.DATA_MATRIX
            BitMatrix matrix = barcodeWriter.encode(content, BarcodeFormat.PDF_417, sideLength, sideLength, qrParam);
            return matrix;
        }
        
    }
    View Code
  • 相关阅读:
    MySQL时间函数
    Linux安装php运行环境
    linux 防火墙配置
    CENTOS启动后网卡启动不了
    价值
    浏览器STATUS_INVALID_IMAGE_HASH报错解决方法
    wordpress更改域名最简单的方法
    Connection to 天mysql failed. [08001] Could not create connection to database server. Attempted ,报错处理方法
    centos实现三个节点高可用
    安装nginx1.16.1版本
  • 原文地址:https://www.cnblogs.com/hero4china/p/6545156.html
Copyright © 2011-2022 走看看