Android-图片压缩详解:原理、方法与实践

这篇具有很好参考价值的文章主要介绍了Android-图片压缩详解:原理、方法与实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在Android应用开发中,处理图片是一个非常常见的需求。然而,大尺寸和高质量的图片可能会占用大量内存,导致应用程序性能下降,甚至引发OOM(Out of Memory)错误。因此,对图片进行合适的压缩是非常重要的。本文将详细介绍Android图片压缩的原理、方法和实践。

1. 图片压缩的原理

图片压缩的本质是降低图片的尺寸(像素)和质量(色彩),以减少图片占用的内存空间。图片压缩可以分为两类:有损压缩和无损压缩。

  • 有损压缩:在压缩过程中,一些图像信息将被丢失,导致图片质量降低。然而,有损压缩能够实现更高的压缩比,从而节省更多的内存空间。JPEG是一种典型的有损压缩算法。
  • 无损压缩:在压缩过程中,图像信息得到保留,图片质量不会降低。然而,无损压缩的压缩比通常较低。PNG是一种典型的无损压缩算法。

2. Android图片压缩的方法

在Android中,有多种方法可以对图片进行压缩。以下是一些常见的图片压缩方法:

2.1 BitmapFactory.Options

BitmapFactory.Options是Android系统提供的一个类,用于设置图片解码时的参数。通过设置BitmapFactory.Options的属性,我们可以实现图片的尺寸和质量压缩。

2.1.1 尺寸压缩

尺寸压缩是通过减少图片的像素来降低图片占用的内存空间。尺寸压缩可以在图片解码时进行,从而避免OOM错误。

BitmapFactory.Options中,有一个属性inSampleSize,表示解码时的缩放比例。例如,inSampleSize=2表示图片的宽度和高度将减小一半,图片占用的内存空间将减小四分之一。

以下是一个使用BitmapFactory.Options进行尺寸压缩的示例:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId,options);
}

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    int inSampleSize = 1;
    int width = options.outWidth;
    int height = options.outHeight;

    if (width > reqWidth || height > reqHeight) {
        int halfWidth = width / 2;
        int halfHeight = height / 2;

        while ((halfWidth / inSampleSize) >= reqWidth && (halfHeight / inSampleSize) >= reqHeight) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

在这个示例中,我们首先使用options.inJustDecodeBounds=true计算inSampleSize,然后使用options.inJustDecodeBounds=false进行实际的图片解码。这样可以避免解码两次图片,提高性能。

2.1.2 质量压缩

质量压缩是通过降低图片的色彩保真度来减少图片占用的内存空间。质量压缩主要针对有损压缩算法,如JPEG。

在Android中,我们可以使用Bitmap.compress()方法对图片进行质量压缩。以下是一个使用Bitmap.compress()进行质量压缩的示例:

public static Bitmap compressBitmap(Bitmap bitmap, int quality) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
    byte[] bytes = outputStream.toByteArray();
    return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}

在这个示例中,我们将原始Bitmap压缩为JPEG格式,并指定压缩质量。压缩质量的范围是0-100,数值越小,压缩比越高,图片质量越低。需要注意的是,质量压缩不会减少Bitmap占用的内存空间,但可以减少图片文件的存储空间。

2.2 第三方库

除了使用Android系统提供的方法,我们还可以使用第三方库对图片进行压缩。以下是一些常见的Android图片压缩库:

  • Luban:一个轻量级的图片压缩库,支持尺寸和质量压缩。Luban使用一种智能算法,可以在保证图片质量的前提下实现高压缩比。
  • Glide:一个强大的图片加载和处理库,支持多种压缩策略。Glide可以根据目标ImageView的尺寸自动进行尺寸压缩,也可以使用Glide.with(context).load(url).thumbnail(scale)方法进行质量压缩。
  • TinyPNG:一个支持PNG和JPEG格式的图片压缩服务。TinyPNG提供了一个Android SDK,可以方便地在Android应用中进行图片压缩。

3. 实践:Android图片压缩

下面我们将通过一个实际示例来演示如何在Android应用中实现图片压缩。这个示例将展示如何使用BitmapFactory.Options进行尺寸压缩和质量压缩,以及如何使用Glide库进行图片压缩。

3.1 创建一个新的Android项目

首先,在Android Studio中创建一个新的Android项目。在这个示例中,我们将使用一个简单的布局,包括一个ImageView和一个Button。用户可以点击Button来选择图片,应用将对图片进行压缩并显示在ImageView上。

3.2 修改布局文件

打开activity_main.xml布局文件,添加一个ImageView和一个Button。代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:scaleType="fitCenter" />

    <Button
        android:id="@+id/button_select_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Select Image" />

</LinearLayout>

3.3 添加图片选择功能

打开MainActivity.java,为Button添加点击事件监听器。当用户点击Button时,我们将启动一个图片选择器,让用户选择一张图片。代码如下:

private static final int REQUEST_CODE_PICK_IMAGE = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button buttonSelectImage = findViewById(R.id.button_select_image);
    buttonSelectImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == REQUEST_CODE_PICK_IMAGE && resultCode == RESULT_OK && data != null) {
        Uri imageUri = data.getData();
        if (imageUri != null) {
            // Load and compress the image
        }
    }
}

3.4 使用BitmapFactory.Options进行图片压缩

onActivityResult()方法中,我们将对用户选择的图片进行尺寸压缩和质量压缩。首先,我们使用BitmapFactory.Options进行尺寸压缩:

private Bitmap decodeSampledBitmapFromUri(Context context, Uri uri, int reqWidth, int reqHeight) {
    InputStream inputStream = null;
    try {
        inputStream = context.getContentResolver().openInputStream(uri);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(inputStream, null, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        inputStream.close();

        inputStream = context.getContentResolver().openInputStream(uri);
        return BitmapFactory.decodeStream(inputStream, null, options);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return null;
}

接下来,我们使用Bitmap.compress()方法进行质量压缩:

private Bitmap compressBitmap(Bitmap bitmap, int quality) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
    byte[] bytes = outputStream.toByteArray();
    return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}

然后,我们将压缩后的图片显示在ImageView上:

ImageView imageView = findViewById(R.id.imageView);
Bitmap compressedBitmap = decodeSampledBitmapFromUri(this, imageUri, imageView.getWidth(), imageView.getHeight());
compressedBitmap = compressBitmap(compressedBitmap, 80);
imageView.setImageBitmap(compressedBitmap);

3.5 使用Glide库进行图片压缩

首先,在build.gradle文件中添加Glide的依赖:

implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

然后,我们可以使用Glide的asBitmap()方法对图片进行尺寸压缩。在onActivityResult()方法中,将之前的代码替换为以下代码:

ImageView imageView = findViewById(R.id.imageView);
Glide.with(this)
     .asBitmap()
     .load(imageUri)
     .into(imageView);

Glide会根据ImageView的尺寸自动进行尺寸压缩。如果需要进行质量压缩,可以使用.thumbnail()方法。

4. 总结

在本文中,我们详细介绍了Android图片压缩的原理、方法和实践。我们学习了如何使用BitmapFactory.Options进行尺寸压缩和质量压缩,以及如何使用第三方库进行图片压缩。希望本文能帮助你更好地理解和应用Android图片压缩技术。文章来源地址https://www.toymoban.com/news/detail-587936.html

到了这里,关于Android-图片压缩详解:原理、方法与实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android-图片压缩(二)-纯干货

    Android - 图片压缩(一)- 项目中取图片转bitmap Android - 图片压缩(二)- 压缩基础 Android - 图片压缩(三)- 剖析鲁班,借鉴参数 Android - 图片压缩(四)- 手撸压缩工具 Android - 图片压缩(五)- 推广使用,开始属于你的工具库 前言:让我们手撸一个图片压缩库,对压缩工具鲁

    2024年02月02日
    浏览(34)
  • Android 简单的视频、图片压缩工具

    首页需要压缩的工具包 1.Gradle 2.添加相关权限(手机得动态申请权限) uses-permission android:name=\\\"android.permission.READ_EXTERNAL_STORAGE\\\"/ uses-permission android:name=\\\"android.permission.WRITE_EXTERNAL_STORAGE\\\"/ 3.使用 使用很简单,直接调用相关方法传入文件路径就能获得压缩之后新文件的路径 1 视频压

    2024年02月13日
    浏览(36)
  • 【android studio实践计算机界面】

    新建项目 1、打开Android Studio 2、创建项目 点击右上角【New Project】 选择“Empty Activity”,然后点击“Next 3、设置项目基本信息 4、等待项目文件加载 打开界面文件 res/layout/activity_main.xml 点击右上角Split,切换显示模式 1、设置线性布局 在这里插入图片描述 2、增加子容器 3、添

    2023年04月19日
    浏览(44)
  • 使用Android Studio实现图片滤镜应用

    简介: 本文将介绍如何使用Android Studio开发一个图片滤镜应用。通过应用中提供的滤镜效果,用户可以对图片进行美化和编辑。我们将使用Android Studio提供的图像处理库和一些常见的滤镜算法来实现这个应用。 步骤一:创建新项目 打开Android Studio并创建一个新的项目。在项目

    2024年02月12日
    浏览(43)
  • Android Studio实现滑动图片验证码

    源代码链接 效果: MainActivity SlideImageView activity_main.xml

    2024年02月13日
    浏览(45)
  • Android Studio设置图片背景(图文讲解)

    首先进入Android studio内部 点击File下拉出现Settings点击进入 点击Appearance 看到Background images右击进入 Image选择图片路径 Opacity设置图片透明度 最后点击OK应用

    2024年02月06日
    浏览(41)
  • Unity Android Studio 混合开发实践(Unity工程导入Android项目进行开发)

    最近接到一个任务是将一个unity开发的游戏接入到现有的Android项目里,然后在现有的App实现点击一个按钮打开游戏,并且在游戏内提供一个可以退出到App的按钮。 整体需求是很明确的,难点主要有两个: 我们公司是做应用开发的,没有任何游戏开发的技能储备。 在游戏中需

    2024年02月11日
    浏览(59)
  • Android Studio开发之路(二)添加图片资源

    第一步:复制要添加的图片 第二步:右键点击项目的res-drawable目录,选择paste粘贴 选择drawable目录 问你是否确定要复制,点击ok即可 然后就可以看到在drawable目录下出现了复制的图片 然后在xml中添加代码就可以显示在界面上了

    2024年02月09日
    浏览(41)
  • 《Android Studio开发实战》学习(八)- 点击按钮切换图片

    在前一篇文章 1 中实现了使用Android Studio开发一个图片展示App,熟悉了简单控件ImageView的使用 2 ,在这里继续研究Android Studio的使用方法。本文的目的是介绍如何开发一个图片切换App,实现点击按钮,在窗口中切换不同的图片。 现在想要设计一个图片切换工具,页面布局是 图

    2024年02月09日
    浏览(36)
  • Android Studio实现解析HTML获取图片URL将图片保存到本地

    效果 项目本来是要做成图片保存到手机然后读取数据后瀑布流展示,但是有问题,目前只能做到保存到手机 activity_main.xml MainActivity ImageItem ImageAdapter

    2024年02月12日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包