Blankj / Blankj/AndroidUtilCode

ImageUtils 中的 compressByQuality二分法处理结果可能不正确

Open
#1,377 1 comment 0 reactions 1 assignee Claimed by @Blankj View on GitHub
bug
Dominant language
Java
Stars
33.6k
Forks
10.6k
PR merge metrics
No merged PRs in 30d

Description

## 描述 Bug

简洁地描述下 Bug。

- AndroidUtilCode 的版本:utilcode:1.30.5

## 相关代码

```
ImageUtils.compressByQuality(final Bitmap src,
final long maxByteSize,
final boolean recycle)
```

该方法中有如下代码
```
int st = 0;
int end = 100;
int mid = 0;
while (st < end) {
mid = (st + end) / 2;
baos.reset();
src.compress(CompressFormat.JPEG, mid, baos);
int len = baos.size();
if (len == maxByteSize) {
break;
} else if (len > maxByteSize) {
end = mid - 1;
} else {
st = mid + 1;
}
}
if (end == mid - 1) {
baos.reset();
src.compress(CompressFormat.JPEG, st, baos);
}
bytes = baos.toByteArray();
```
这个方式处理的结果可能不正确,举个例子:比如有个图片压缩质量为50.7的时候等于最大值,因此第一次取值50则小于限制值,命中st=mid+1,结果st直接为51了,直到最终 end=50 == mid-1 获取了压缩质量为51的情况,此时已经超过了最大限度的值,我认为此处应该对end值进行判断,使用:
```
if (end == mid - 1) {
baos.reset();
if (end > 0) {
src.compress(CompressFormat.JPEG, 0, baos);
} else {
src.compress(CompressFormat.JPEG, end, baos);
}
}
```
或者对上一次最合适的值进行标记
```
int st = 0;
int end = 100;
int mid = 0;
int lastBestQuality = mid;
while (st < end) {
mid = (st + end) / 2;
baos.reset();
src.compress(CompressFormat.JPEG, mid, baos);
int len = baos.size();
if (len == maxByteSize) {
lastBestQuality = mid;
break;
} else if (len > maxByteSize) {
end = mid - 1;
} else {
lastBestQuality = mid;
st = mid + 1;
}
}
if (lastBestQuality != mid) {
baos.reset();
src.compress(CompressFormat.JPEG, lastBestQuality, baos);
}
bytes = baos.toByteArray();
```
以上,当然,也可能是我一时陷入一个思维死角转不出来,期待您的回复和解答。

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.