【软通动力】HarmonyOS三方件开发指南(7)——compress组件 原创 精华

软通田可辉
发布于 2021-2-1 15:54
浏览
17收藏

1. 组件compress功能介绍
1.1.  组件介绍:
        compress是一个轻量级图像压缩库。compress允许将大照片压缩成小尺寸的照片,图像质量损失非常小或可以忽略不计。

1.2.  手机模拟器上运行效果:
   【软通动力】HarmonyOS三方件开发指南(7)——compress组件-鸿蒙开发者社区

【软通动力】HarmonyOS三方件开发指南(7)——compress组件-鸿蒙开发者社区

2. 组件compress使用方法
2.1.  添加依赖
        将compress-debug.har复制到应用的entry\libs目录下即可(由于build.gradle中已经依赖的libs目录下的*.har,因此不需要再做修改)。

2.2.  设置布局

<DependentLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:width="match_parent"
    ohos:height="match_parent"
    ohos:background_element="#FFFFFF">
    <Image
        ohos:id="$+id:image1"
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:image_src="$media:dog1.PNG"/>
    <Text
        ohos:id="$+id:text"
        ohos:width="match_content"
        ohos:height="match_content"
        ohos:text=""
        ohos:text_size="19fp"
        ohos:text_color="#1C1C1C"
        ohos:top_padding="8vp"
        ohos:bottom_padding="8vp"
        ohos:right_padding="70vp"
        ohos:left_padding="70vp"
        ohos:center_in_parent="true"
        ohos:align_parent_bottom="true"
        ohos:bottom_margin="120vp"/>
    <Button
        ohos:id="$+id:choose_button"
        ohos:width="match_content"
        ohos:height="match_content"
        ohos:text="Choose Image"
        ohos:text_size="19fp"
        ohos:text_color="#FFFFFF"
        ohos:top_padding="8vp"
        ohos:bottom_padding="8vp"
        ohos:right_padding="70vp"
        ohos:left_padding="70vp"
        ohos:background_element="$graphic:background_button"
        ohos:center_in_parent="true"
        ohos:align_parent_bottom="true"
        ohos:bottom_margin="75vp"/>
    <Button
        ohos:id="$+id:button"
        ohos:width="match_content"
        ohos:height="match_content"
        ohos:text="Compress"
        ohos:text_size="19fp"
        ohos:text_color="#FFFFFF"
        ohos:top_padding="8vp"
        ohos:bottom_padding="8vp"
        ohos:right_padding="70vp"
        ohos:left_padding="70vp"
        ohos:background_element="$graphic:background_button"
        ohos:center_in_parent="true"
        ohos:align_parent_bottom="true"
        ohos:bottom_margin="15vp"/>
</DependentLayout>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.

2.3.  图像压缩
核心类:Compressor

核心方法:

(1)自定义压缩:

public static File customCompress(Context context, File file, int width, int height, int quality) throws IOException 
  • 1.

参数:

context - 应用程序上下文

file - 待压缩图片抽象路径名

width - 压缩后宽度

height - 压缩后高度

quality - 图片压缩质量,范围0~100

结果:

返回压缩后图片抽象路径名。

异常:

发生I/O异常

(2)默认压缩:

public static File defaultCompress(Context context, File file) throws IOException
  • 1.

参数:

context - 应用程序上下文

file - 待压缩图片抽象路径名

结果:

返回压缩后图片抽象路径名。

异常:

发生I/O异常

简单示例:

运行示例前需要在模拟器保存一张截图或使用相机功能照一张照片

public void onStart(Intent intent) {

    super.onStart(intent);

    super.setUIContent(ResourceTable.Layout_ability_main);



    // 请求文件的读取权限

    String[] permissions = {"ohos.permission.READ_USER_STORAGE"};

    requestPermissionsFromUser(permissions, 0);



    // 获取压缩按钮并绑定事件

    Button button = (Button) findComponentById(ResourceTable.Id_button);

    if (button != null) {

        // 为按钮设置点击回调

        button.setClickedListener(new Component.ClickedListener() {

            @Override

            public void onClick(Component component) {

                try {

                    File file = new File(System.getProperty("java.io.tmpdir") + File.separator + tmpName);

                    HiLog.error(LOG_LABEL, "old size..." + file.length() +  " ...b");



                    // 默认压缩

                    // File newFile = Compressor.defaultCompress(file);



                    // 自定义压缩

                    File newFile = Compressor.customCompress(getContext(), file, 500, 1000, 60);

                    Text text = (Text) findComponentById(ResourceTable.Id_text);

                    text.setText("size: " + newFile.length() + " b");

                    HiLog.error(LOG_LABEL, "new size..." + newFile.length() +  " ...b");

                    PixelMap newPixelMap = Compressor.decode(newFile);

                    Image image = (Image) findComponentById(ResourceTable.Id_image1);

                    image.setPixelMap(newPixelMap);

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        });

    }

    // 获取选择图片按钮并绑定事件

    Button chooseButton = (Button) findComponentById(ResourceTable.Id_choose_button);

    if (chooseButton != null) {

        // 为按钮设置点击回调

        chooseButton.setClickedListener(new Component.ClickedListener() {

            @Override

            public void onClick(Component component) {

                DataAbilityHelper helper = DataAbilityHelper.creator(getContext());

                try {

                    ResultSet resultSet = helper.query(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, null, null);

                    while (resultSet != null && resultSet.goToNextRow()) {

                        // 互殴媒体库的图片

                        int id = resultSet.getInt(resultSet.getColumnIndexForName(AVStorage.Images.Media.ID));

                        HiLog.error(LOG_LABEL, "id:..." + id +  " ...");

                        Uri uri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, "" + id);

                        // 根据图片的uri打开文件并保存到临时目录中

                        FileDescriptor fileDescriptor = helper.openFile(uri, "r");

                        ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();

                        decodingOpts.sampleSize = ImageSource.DecodingOptions.DEFAULT_SAMPLE_SIZE;

                        ImageSource imageSource = ImageSource.create(fileDescriptor, null);

                        PixelMap pixelMap = imageSource.createThumbnailPixelmap(decodingOpts, true);

                        ImagePacker imagePacker = ImagePacker.create();

                        tmpName = UUID.randomUUID().toString();

                        File file = new File(System.getProperty("java.io.tmpdir") + File.separator + tmpName);

                        FileOutputStream outputStream = new FileOutputStream(file);

                        ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();

                        packingOptions.quality = 100;

                        boolean result = imagePacker.initializePacking(outputStream, packingOptions);

                        result = imagePacker.addImage(pixelMap);

                        long dataSize = imagePacker.finalizePacking();

                        // 显示图片和图片大小

                        Text text = (Text) findComponentById(ResourceTable.Id_text);

                        text.setText("size: " + file.length() + " b");

                        Image image = (Image) findComponentById(ResourceTable.Id_image1);

                        image.setPixelMap(pixelMap);

                    }

                } catch (DataAbilityRemoteException | FileNotFoundException e) {

                    e.printStackTrace();

                }

            }

        });

    }

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.

3. 组件compress开发实现
3.1.  拷贝图片制临时目录
传入的图片路径拷贝临时文件到应用的临时目录。

private static File copyToCache(Context context, File imageFile) throws IOException {

    PixelMap pixelMap = decode(imageFile);

    String cachePath = context.getCacheDir() + File.separator + imageFile.getName();

    File cacheFile = new File(cachePath);

    int quality = 100; // 压缩质量

    refreshTmpFile(pixelMap, cacheFile, quality);

    return cacheFile;

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

 3.2.  图片解码
对临时目录里的图片进行解码

private static PixelMap decode(File file, int width, int height) {

    ImageSource imageSource = ImageSource.create(file, null);
    mageSource.DecodingOptions decodingOpts = new

ImageSource.DecodingOptions();
    decodingOpts.desiredSize = new Size(width, height);
    return imageSource.createPixelmap(decodingOpts);

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

 3.3.  图片编码
按照开发人员设定的规则进行编码,生成新图片

private static void refreshTmpFile(PixelMap pixelMap, File file, int quality)

throws IOException {

    ImagePacker imagePacker = ImagePacker.create();

    ImagePacker.PackingOptions options = new ImagePacker.PackingOptions();

    options.quality = quality;

    imagePacker.initializePacking(new FileOutputStream(file), options);

    imagePacker.addImage(pixelMap);

    imagePacker.finalizePacking();

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

 

项目源代码地址:https://github.com/isoftstone-dev/Compressor_Harmony

欢迎交流:HWIS-HOS@isoftstone.com

 

 

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-2-3 17:13:32修改
20
收藏 17
回复
举报
20
6
17
6条回复
按时间正序
/
按时间倒序
lingyuli
lingyuli

可以的,学习一下。

回复
2021-2-2 09:37:10
软通田可辉
软通田可辉 回复了 lingyuli
可以的,学习一下。

欢迎常来,后续还会有更多优质内容持续更新

回复
2021-2-5 09:34:42
粉粉gg
粉粉gg

请问,是否支持压缩网络图片?

回复
2021-2-8 09:21:38
软通田可辉
软通田可辉 回复了 粉粉gg
请问,是否支持压缩网络图片?

网络图片无法直接压缩,需要先在本地保存才能进行压缩。

回复
2021-2-8 15:45:38
张荣超_九丘教育
张荣超_九丘教育

👍👍👍

回复
2021-2-9 22:58:53
维维师兄
维维师兄

讲解细致

回复
2021-2-10 14:34:33
回复
    相关推荐