Android实现对图片的缩放、剪切、旋转、存储

2023-11-11

最近看到一篇关于图像处理的blog,感觉挺有用的,转载过来收藏下


一、问题描述

在开发中,当我们需要的有一张大图片同时还需要一些小图片时,我们只需要通过代码对此图片进行不同比例的缩放即可,这样大大节约资源,减小了安装包的尺寸 。除缩放外,我们还经常对图片进行其他操作如裁剪、旋转、存储等。

这样我们可以编写对于图片进行处理的通用组件,方便开发。下面就分享一下对图片进行处理的组件BitmapUtil,案例界面:

二、技术点描述

1、 通过 BitmapFactory 取得Bitmap

Bitmap bm=BitmapFactory.decodeStream(InputStream is );

2、Bimap的createBitmap()方法

Bitmap newbm = Bitmap.createBitmap( Bitmap s, int x, int y, int w, int h, Matrix m, boolean f);

该方法可实现位图的缩放、裁剪、旋转操作

参数说明:

Bitmap s:要处理的原始位图

int x ,y:起始位置坐标

int w:要截的图的宽度

int h:要截的图的宽度

Matrix m 矩阵,主要是用于平面的缩放、平移、旋转

boolean f:是否保证等比

返回值:返回处理后的Bitmap

三、BitmapUtil组件

可实现对图片进行按比例缩放、图片按比例裁剪、圆形图片处理等方法,实现功能如下:

1、readBitmapById()方法

/**
 * 通过资源id转化成Bitmap
 * @param context
 * @param resId
 * @return
 */
public static Bitmap readBitmapById(Context context, int resId){
  BitmapFactory.Options opt = new BitmapFactory.Options();
  opt.inPreferredConfig = Bitmap.Config.RGB_565;
  opt.inPurgeable = true;
  opt.inInputShareable = true;
  InputStream is = context.getResources().openRawResource(resId);
  return BitmapFactory.decodeStream(is, null, opt);
}

2、scaleImage()方法,实现按指定宽高缩放图片

执行效果如图:

/**
* 缩放图片
   * @param bm 要缩放图片
   * @param newWidth 宽度
   * @param newHeight 高度
   * @return处理后的图片
   */
  public static  Bitmap  scaleImage(Bitmap bm, int newWidth, int newHeight){
    if (bm == null){
      return null;
    }
    int width = bm.getWidth();
    int height = bm.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleHeight);
    Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix,true);
    if (bm != null & !bm.isRecycled()){
      bm.recycle();//销毁原图片
      bm = null;
    }
    return newbm;
  }

3、imageCrop()方法

执行效果如图:

/**
 * 按照一定的宽高比例裁剪图片
 * @param bitmap 要裁剪的图片
 * @param num1 长边的比例
 * @param num2 短边的比例
 * @param isRecycled是否回收原图片
 * @return 裁剪后的图片
 */
public static Bitmap  imageCrop(Bitmap bitmap, int num1, int num2, boolean isRecycled){
  if (bitmap == null){
    return null;
  }
  int w = bitmap.getWidth(); // 得到图片的宽,高
  int h = bitmap.getHeight();
  int retX, retY;
  int nw, nh;
  if (w > h){
    if (h > w * num2 / num1){
      nw = w;
      nh = w * num2 / num1;
      retX = 0;
      retY = (h - nh) / 2;
    } else{
      nw = h * num1 / num2;
      nh = h;
      retX = (w - nw) / 2;
      retY = 0;
    }
  } else{
    if (w > h * num2 / num1){
      nh = h;
      nw = h * num2 / num1;
      retY = 0;
      retX = (w - nw) / 2;
    } else{
      nh = w * num1 / num2;
      nw = w;
      retY = (h - nh) / 2;
      retX = 0;}
  }
  Bitmap bmp = Bitmap.createBitmap(bitmap, retX, retY, nw, nh, null,false);
  if (isRecycled && bitmap != null && !bitmap.equals(bmp)&& !bitmap.isRecycled()){
    bitmap.recycle();//回收原图片
    bitmap = null;
  }
  return bmp;
}

4、toRoundCorner()实现将图片转圆角

执行效果如图:

/**
 *图片转圆角 
 * @param bitmap需要转的bitmap
 * @param pixels转圆角的弧度
 * @return 转圆角的bitmap
 */
public static Bitmap toRoundCorner(Bitmap bitmap, int pixels)    {
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
      bitmap.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(output);
    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
    final RectF rectF = new RectF(rect);
    final float roundPx = pixels;
    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);
    if (bitmap != null && !bitmap.isRecycled())
    {
  bitmap.recycle();
    }
    return output;
}

5、toRoundBitmap()方法将图像裁剪成圆形

执行效果如图:

public static Bitmap toRoundBitmap(Bitmap bitmap){
if (bitmap == null){
      return null;
    }
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    float roundPx;
    float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
    if (width <= height){
      roundPx = width / 2;
      top = 0;
      bottom = width;
      left = 0;
      right = width;
      height = width;
      dst_left = 0;
      dst_top = 0;
      dst_right = width;
      dst_bottom = width;
    } else{
      roundPx = height / 2;
      float clip = (width - height) / 2;
      left = clip;
      right = width - clip;
      top = 0;
      bottom = height;
      width = height;
      dst_left = 0;
      dst_top = 0;
      dst_right = height;
      dst_bottom = height;
    }
    Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    Canvas canvas = new Canvas(output);
    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect src = new Rect((int) left, (int) top, (int) right,
        (int) bottom);
    final Rect dst = new Rect((int) dst_left, (int) dst_top,
        (int) dst_right, (int) dst_bottom);
    final RectF rectF = new RectF(dst);
    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, src, dst, paint);
    if (bitmap != null && !bitmap.isRecycled()){
      bitmap.recycle();
      bitmap = null;
    }
    return output;
  }

6、rotaingImageView()方法,实现旋转图片

执行效果如图:

/**
 * 旋转图片
 * @param angle 旋转角度
 * @param bitmap 要处理的Bitmap
 * @return 处理后的Bitmap
 */
public static Bitmap rotaingImageView(int angle, Bitmap bitmap)
{
  // 旋转图片 动作
  Matrix matrix = new Matrix();
  matrix.postRotate(angle);
  // 创建新的图片
  Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
      bitmap.getWidth(), bitmap.getHeight(), matrix, true);
  if (resizedBitmap != bitmap && bitmap != null && !bitmap.isRecycled()){
    bitmap.recycle();
    bitmap = null;
  }
  return resizedBitmap;
  }

7、saveBmpToSd()实现将保存Bitmap到sdcard

public static boolean saveBmpToSd(String dir, Bitmap bm, String filename,
    int quantity, boolean recyle) {
  boolean ret = true;
  if (bm == null) {
    return false;}
  File dirPath = new File(dir);
  if (!exists(dir)) {
    dirPath.mkdirs();
  }
  if (!dir.endsWith(File.separator)) {
    dir += File.separator;
  }
  File file = new File(dir + filename);
  OutputStream outStream = null;
  try {
    file.createNewFile();
    outStream = new FileOutputStream(file);
    bm.compress(Bitmap.CompressFormat.JPEG, quantity, outStream);
  } catch (Exception e) {
    e.printStackTrace();
    ret = false;
  } finally {
    try {
      if (outStream != null) outStream.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    if (recyle && !bm.isRecycled()) {
      bm.recycle();
      bm = null;
    }
  }
  return ret;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android实现对图片的缩放、剪切、旋转、存储 的相关文章

  • 在位图上绘制长字符串会导致绘图问题

    我正在将一个长字符串绘制到位图 超过一百万个字符 包括多行字符 r n 由一个写StringBuilder 我的文本转位图代码如下 public static Bitmap GetBitmap string input Font input
  • 如何从字符串设置 imageView 的图像?

    我在 res drawable mdpi 目录中有一个条目列表和一些位图文件 我试图通过生成路径字符串并使用位图工厂来加载与从列表中选择的字符串值相对应的图像 问题是我认为我的路径不正确 因为位图始终为空 即使对于默认图像也是如此 Stri
  • Direct2D 位图画笔拉长

    我必须在屏幕外位图上绘制形状 但是当我尝试渲染位图时遇到一个奇怪的问题 这就是图像的显示方式 这就是我查看位图的方式 以下是我用来创建位图画笔的代码 const auto size renderTarget gt GetSize const
  • 如何在Android中加载大图像并避免内存不足错误?

    我正在开发一个使用大图像的应用程序 1390 870 150kb 50kb 我在点击触发器 ImageView 时添加图像 在某个时刻我遇到内存不足错误 java lang OutOfMemoryError E AndroidRuntime
  • Android 的 BitmapFactory 解码函数

    我遇到问题 decodeStream功能 File cacheMap new File context getCacheDir test GIF if cacheMap exist FileInputStream is new FileIn
  • 如何将android中捕获的图像保存到php?

    我们已经在 android 和 php 上尝试过这个代码 请看下面的代码 Android Scn setOnClickListener new OnClickListener Override public void onClick Vie
  • 当将位图加载为 Windows 资源时,是否有办法保留 BITMAPFILEHEADER?

    我一直在使用测试一些东西SFML 1 4 http sfml dev org 简单快速的多媒体库 采用 C 和 Visual C 2008 Express Edition 为了避免我的图形程序出现外部图像 我正在测试sf Image Loa
  • 将专用 NV12 视频帧转换为 RGB

    我有一个使用 Android MediaCodec 解码的 H264 流 当我查询输出 MediaFormat 时 颜色格式为 2141391875 显然 这是一种专门的 NV12 变体 称为 HAL PIXEL FORMAT NV12 A
  • 使用 Objective C 在 ios 中将 jpeg 转换为位图? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我没有找到任何示例或库将 Jpeg 图像转换为 24 位 BITMAP 图像 我已经在 android 和 java 中创建了示例 但
  • 无法在 Android 中将矢量可绘制对象转换为位图可绘制对象

    我正在尝试将位图转换为字节数组 其中我将矢量可绘制图像转换为位图 然后将其转换为字节数组 但是当我打开应用程序时 它向我显示错误类强制转换异常无法将矢量可绘制图像转换为位图可绘制 Resources res getResources Dra
  • 将彩色透明png转换为单色

    我正在使用位图 C 想知道如何将彩色 png 图像转换为仅一种颜色 我希望图像中的所有可见颜色都变成白色 透明的部分应该保持透明 我将在灰色背景下显示这些 如果图像不使用 Alpha 通道来实现透明度 则将执行以下操作 Bitmap ima
  • 如何从位图中删除白色背景色

    我想删除位图中的白色背景颜色 Bitmap capcha new Bitmap C image jpg pictureBox1 Image capcha 但我想在我的 pictureBox1 中仅显示背景中存在的没有白色的图像 尝试在验证码
  • Java Paint 组件转换为位图

    我需要在位图中绘制组件及其所有子组件的内容 如果我想绘制整个组件 以下代码可以完美运行 public void printComponent Component c String format String filename throws
  • 如何从灰度字节缓冲区图像创建位图?

    我正在尝试使用新的 Android 人脸检测移动视觉 API 来处理帧图像 所以我创建了自定义检测器来获取帧并尝试调用 getBitmap 方法 但它为空 所以我访问了帧的灰度数据 有没有办法从它或类似的图像持有者类创建位图 public
  • 绑定Xaml位图图像

    我有位图图像变量 我想将其绑定到我的 xaml 窗口 System Reflection Assembly thisExe thisExe System Reflection Assembly GetExecutingAssembly st
  • Osmdroid:如何从我自己的位图(图块)创建和加载地图?

    我开始使用 Osmdroid 我想使用这项技术来显示有关 F1 赛道的地图 我有一张大图片 我可以将它切割成更小的图块 我可以修改osmdroid库来上传这些图片吗 我想将这些位图 图块 保存在我的资产文件夹中 我非常不知道如何做到这一点
  • view.getDrawingCache() 在 Android API 28 中已弃用

    在 Android API 28 中view getDrawingCache 已被弃用 是否有任何更新的解决方案来生成 android 中特定视图的位图 获取视图位图的两种方法 使用画布 使用像素 API Canvas Java Bitma
  • Android 在画布上遮罩位图生成黑色空间

    我有一个蒙版位图 一半是红色 一半是透明的 如下所示https www dropbox com s 931ixef6myzusi0 s 2 png https www dropbox com s 931ixef6myzusi0 s 2 pn
  • 有没有办法在 asp 图像控件上显示动态生成的位图?

    在我的代码中 我使用 C 和 ASP NET 动态创建位图 我需要将其显示在 asp 图像控件上 无论如何 有没有办法在不使用处理程序的情况下做到这一点 使用 ashx 处理程序更好 因为它适用于所有浏览器 并且您可以在客户端上缓存输出图像
  • 如何使用 C# 将 Windows 窗体面板作为位图获取?

    我有一个 Windows 窗体 其中一个面板上有多个控件 面板并不占据所有的表单空间 而只占据一小部分 我想知道是否有某种方法可以将面板 带有所有子控件 的显示检索为位图 就像屏幕截图一样 但仅裁剪到面板 我没有查看屏幕截图 因为面板位于可

随机推荐

  • 【python】如何把你的python包发布出去(pip install)

    python 如何把你的python包发布出去 pip install 介绍 实际上分为两步 打包 发布 我们要发布的网站是https pypi org 也就是用户通过pip install XXX 就可以安装你的包 1 通过setupto
  • python环境的安装(Windows)

    步骤一安装 打开python官网https www python org 点击Downloads 选择Windows进入后根据自己的电脑是32位还是64位 右击此电脑属性查看 选择相应的版本下载 注意 要选择Windows installe
  • 【2023硅谷数模笔试题】~ 题目及参考答案

    本章目录 0 前言 1 题目 答案 第一题 第二题 第三题 第四题 第五题 第六题 第七题 第八题 第九题 第十题 第十一题 声明 0 前言 哈喽 二舅 最近和你们一样 不断被鞭策 今天抽个小空给大家带来的是前几天做的一套笔试题 名称如标题
  • 谈谈tomcat的优化经验

    第一次写博客 搜集了很多的优化经验 然后自己归纳下来 大概有7条 没涉及到的欢迎大家补充 1 优化方法 加大tomcat使用的jvm的内存 具体操作 Tomcat默认可以使用的内存为128MB 可在配置文件或环境变量里增加使用内存 在配置文
  • IDEA创建Maven工程后卡死,问题分析及解决

    问题 同标题 IDEA创建Maven工程后卡死 网上收集经验后 大多数版本为2020及以后的问题 但应该是同样的问题 即archetype catalog xml文件太大源地址下载过慢 这里记录一下方便的解决方式 解决方法 提前将arche
  • IDEA 热部署插件 -- JRebel

    从idea找到设置Plugins插件 激活参考http www javatiku cn idea 51 html 服务器链接 http idea javatiku cn ad4bd706 15a3 4ecf b3e3 c7b6a64942b
  • GCC强大背后

    前记 经常浏览博客园的同学应该会觉得本文有标题党之嫌 这个标题的句式来自于MiloYip大牛的大作 C 强大背后 在此 向Milo兄致意 GCC 全称GNU Compiler Collection 是一套GNU开发的编译器环境 它的创始人便
  • ENVI监督分类及精度评价

    最近协助同学做了完整的监督分类数据 特此记录下来 对于ENVI监督分类 是每一个遥感从业者掌握的最基础的一个方法 但是完整的监督分类流程和精度评价 估计往往认识不够 所以以下的分享还是有点意义 监督分类 又称训练分类法 用被确认类别的样本像
  • 34岁,转行软件测试工程师后月薪8K,我仍然坚持转行!

    本人今年34岁 目前已成功转行软件测试工程师 月薪8K 对于很多人而言 我这个年纪转行不仅有些晚 还要担许多未知的职场风险 我深知自己这一路并不容易 以下就和大家分享一下我的转行经历吧 到了我这个年纪的人 大多都被社会这个大染缸染得面目全非
  • Docker搭建ELK日志采集服务及Kibana可视化图表展示

    架构 ES docker network create elk mkdir p opt ELK es data chmod 777 opt ELK es docker run d name elasticsearch net elk p 9
  • Vue——插件

    目录 介绍 编写一个插件 介绍 插件 Plugins 是一种能为 Vue 添加全局功能的工具代码 下面是如何安装一个插件的示例 import createApp from vue const app createApp app use my
  • .NET混淆器 Dotfuscator v4.43.1新版发布!允许某些外部程序集输入!

    Dotfuscator是一个 NET的Obfuscator 它提供企业级的应用程序保护 大大降低了盗版 知识产权盗窃和篡改的风险 Dotfuscator的分层混淆 加密 水印 自动失效 防调试 防篡改 报警和防御技术 为世界各地成千上万的应
  • UE4_AsyncTask应用笔记

    在开发过程中如果把所有的逻辑都放到GameThread里 难免会卡顿 因此这时候 往往会用到多线程 UE4提供的多线程解决方案有三种 这里我们着重说一下AsyncTask的应用 一般来说 用AsyncTask都是一些业务逻辑不复杂的交给它来
  • Sequelize的原始查询的时区问题

    在postgres数据库sequelize的raw query也是受时区影响的 同样的语句 用sequelize直接执行某些跟时间相关的query和在数据库执行是不一样的 语句如下 update table A set is enable
  • 树莓派4b基础入门

    AI嵌入式设备相关内容已合成AIOT专栏 其中包含rknn系列开发板 计算棒 jetson系列 树莓派等详细操作 实战项目源码 让小白从入门到精通 欢迎订阅 AI嵌入式设备已有专栏详细讲解 目录 一 树莓派百科知识 二 树莓派4B图解及配件
  • 0xc000007b的解决办法(续)

    最后更新 2019 3 23 请大家首先确定已经按照原文的方法及步骤尝试过 但是还是没有解决问题再来看这篇文章 如果你还没有看过原文 请先看原文 http blog csdn net VBcom article details 607070
  • ubuntu20.04交叉编译移植OpenCV4.7.0和QT5.12.12至ARM64位平台LKD3588(开发板为ubuntu20.04系统)(二)

    序 opencv部署到开发板 由于GTK问题导致opencv无法使用Gui 只能交叉编译QT 并为其作为gui供opencv使用 一 PC端交叉编译QT5 12 12 先编译tslib文件 tslib文件的下载链接 https github
  • gcc -D_REENTRANT

    在使用多线程函数时 我们经常使用编译器选项 lpthread和 D REENTRANT 前者告诉链接器链接库文件libpthread so 对于后者 gcc使用 D选项定义宏 REENTRANT的值为1 在 POSIX C SOURCE宏被
  • idea unknow facet type web 解决方案

    菜单 gt Preferences gt Plugins 添加tomcat支持 如图 然后 项目project setting中 可以添加 web类型的facets了 pasting
  • Android实现对图片的缩放、剪切、旋转、存储

    最近看到一篇关于图像处理的blog 感觉挺有用的 转载过来收藏下 一 问题描述 在开发中 当我们需要的有一张大图片同时还需要一些小图片时 我们只需要通过代码对此图片进行不同比例的缩放即可 这样大大节约资源 减小了安装包的尺寸 除缩放外 我们