Android WebP 그림 압축 및 전송
4g 시대 까지 유 동량 은 여전히 귀중 한 것 이 었 다.한편,모 바 일 네트워크 전송 에서 가장 많은 데 이 터 를 차지 하 는 캐리어:그림 은 우리 모 바 일 개발 자 들 이 주목 해 야 할 문제 가 되 었 다.
우리 가 주목 하 는 문 제 는 그림 의 부피 와 품질 이 어떻게 비교적 조화 로 운 균형 에 이 르 는 지,품질 이 좋 은 그림 을 얻 는 동시에 부피 가 너무 크 지 않 기 를 바 라 는 것 이다.
시 대 를 앞서 가 는 구 글 은 웹 P 라 는 좋 은 답 을 내 놓 았 다.
WebP 는 그림 파일 형식 으로 같은 압축 기준 에서 webp 의 손실 압축 은 jpg 보다 25-34%작다.내 테스트 에 서 는 50%가 작 을 때 도 있다.
2.대기업 배 서
WebP 는 2010 년 첫 번 째 버 전 을 발표 한 지 6 년 이 되 었 다.구 글 산하 각종 사이트 G+와 대표 적 인 유 튜브,그의 동 영상 파일 형식 인 WebM 은 WebP 구 조 를 바탕 으로 한 것 이다.
텐 센트,타 오 바 오,미 단도 일부 활용 된다 고 한다.
3.안 드 로 이 드 엔 드 JPG 변환 WebP
RxJava 스 레 드 변환:
String[] imgs = new String[]{"1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg"};
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/test/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// test = Api.getBuilder().create(Test.class);
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE
, Manifest.permission.READ_PHONE_STATE
, Manifest.permission.CAMERA};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(permissions, 0);
}
compress();
}
private void compress() {
Observable.from(imgs)
.subscribeOn(Schedulers.io())
.doOnNext(new Action1<String>() {
@Override
public void call(String imgName) {
compress(imgName);
}
})
.subscribe();
}
private void compress(String imgName) {
try {
File file = new File(path, imgName);
Log.i("compress", "jpg start");
byte[] bytes = BitmapUtil.compressBitmapToBytes(file.getPath(), 600, 0, 60, Bitmap.CompressFormat.JPEG);
File jpg = new File(path, imgName + "compress.jpg");
FileUtils.writeByteArrayToFile(jpg, bytes);
Log.i("compress", "jpg finish");
Log.i("compress", "----------------------------------------------------");
Log.i("compress", "webp start");
byte[] bytes1 = BitmapUtil.compressBitmapToBytes(file.getPath(), 600, 0, 60, Bitmap.CompressFormat.WEBP);// , , , , 。
File webp = new File(path, imgName + "compress.webp");
FileUtils.writeByteArrayToFile(webp, bytes1);
Log.i("compress", "webp finish");
} catch (IOException e) {
e.printStackTrace();
}
}
내 테스트 기기 도 원 플러스 1,CM 13 이기 때문에 그 에 상응하는 권한 을 가 져 야 한다.RxJava 를 이용 하여 스 레 드 작업 을 하고 io 스 레 드 에서 시간 소모 작업 을 했 습 니 다.
public static byte[] compressBitmapToBytes(String filePath, int reqWidth, int reqHeight, int quality, Bitmap.CompressFormat format) {
Bitmap bitmap = getSmallBitmap(filePath, reqWidth, reqHeight);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(format, quality, baos);
byte[] bytes = baos.toByteArray();
bitmap.recycle();
Log.i(TAG, "Bitmap compressed success, size: " + bytes.length);
return bytes;
}
public static Bitmap getSmallBitmap(String filePath, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
// options.inPreferQualityOverSpeed = true;
return BitmapFactory.decodeFile(filePath, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
int h = options.outHeight;
int w = options.outWidth;
int inSampleSize = 0;
if (h > reqHeight || w > reqWidth) {
float ratioW = (float) w / reqWidth;
float ratioH = (float) h / reqHeight;
inSampleSize = (int) Math.min(ratioH, ratioW);
}
inSampleSize = Math.max(1, inSampleSize);
return inSampleSize;
}
입력 한 너비 와 높 은 값 에 따라 해상도 의 축소 비율 을 계산 한 다음 에 입력 한 압축 품질 수치 에 따라 그림 을 압축 하여 압축 된 bitmap 를 얻 은 다음 에 원가 파일 을 저장 합 니 다.이것 은 매우 흔히 볼 수 있 는 그림 압축 수단 이다.
4.WebP 대비
저 는 일상생활 에서 찍 은 사진 으로 간단 한 비교 테스트 를 합 니 다.엄밀 하지 않 고 간단 한 참고 만 제공 합 니 다.
사진 촬영 장 비 는 CM 13 을 칠 한 1 더하기 1 이다.사진 촬영 장면 은 모두 일상생활 에서 특히 흔히 볼 수 있 는 것 이다.
다음은 원본 미리 보기 입 니 다.하나씩 놓 지 않 겠 습 니 다.너무 큽 니 다.
해상 도 를 줄 이 고 동시에 품질 을 압축 하 다.
파일 이름
사진
압축 후 jpg
압축 후 webp
압축 비
1.jpg
5760 kb
98 kb
74 kb
24.49%
2.jpg
4534 kb
64 kb
35 kb
45.31%
3.jpg
4751 kb
93 kb
68 kb
26.88%
4.jpg
7002 kb
121 kb
95 kb
21.49%
5.jpg
5493 kb
111 kb
91 kb
18.02%
평균 압축 비 는 27.24%
원 그림 의 크기 에 따라 해상 도 를 줄 이지 않 고 품질 만 압축 합 니 다.
파일 이름
사진
압축 후 jpg
압축 후 webp
압축 비
3.jpg
4751 kb
796 kb
426 kb
46.48%
이로써 우 리 는 웹 p 를 편리 하 게 사용 하여 그림 을 더욱 극 대화 압축 하고 그림 의 부피 와 품질 을 동시에 고려 했다.
어,csdn 은 웹 p 의 사진 을 올 리 는 것 을 지원 하지 않 습 니 다.너 희 는 압축 가방 을 볼 수 있다.
제 가 귀찮아 서 압축 가방 을 안 넘 길 것 같 아 요.........................................................
눈 을 크게 뜨 고 어떤 차이 가 있 는 지 비교 해 보 세 요.해상 도 를 줄 이지 않 고 품질 만 압축 합 니 다.이 3.jpg 는 46.48%의 압축 비 입 니 다.
이 장면 은 밤 에 조명 이 충분 한 실내 에서 밥 을 먹고 찍 은 것 이다.
5.Gzip 으로 압축
방금 로 컬 그림 에 대한 압축 이 었 습 니 다.다음은 서버 에 그림 을 전송 해 야 합 니 다.이 과정 은 여전히 최적화 공간 이 있 는데 바로 Gzip 을 이용 하 는 것 이다.
Gzip 의 역할 대상 은 전체 요청 체 이 며,구체 적 으로 는 요청 체 의 내용 을 역 압축 하여 pc 상의 zip 와 유사 합 니 다.
Gzip 압축 요청 체 는 header:"Content-Encoding:gzip"을 추가 해 야 합 니 다.
이 일 은 Retrofit 가 너 를 도와 잘 할 것 이다.
백 엔 드 서버 가 이 유형의 요청 을 받 으 면 요청 체 에 대한 압축 을 풀 수 있 기 때문에 백 엔 드 지원 이 필요 합 니 다.
또한,Gzip 은 비교적 큰 요청 체 압축 효과 가 좋 으 며,특히 압축 되 지 않 은 일반 텍스트 형식 에 대해 서도 주의해 야 합 니 다.
요청 이 원래 작 으 면 gzip 압축 을 사용 하지 마 세 요.압축 가방 의 메타 데 이 터 는 요청 체 보다 더 크 고 얻 는 것 보다 잃 는 것 이 많 을 수 있 습 니 다.너 는 스스로 테스트 해 볼 수 있다.나 는 zip 와 gzip 의 압축 사전 이 비교적 유사 하 다 고 생각한다.직접 pc 에서 테스트 할 수 있다.
6.Retrofit 요청 Gzip 압축
네트워크 요청 에 있어 서 제 프로젝트 에 서 는 Retrofit(OKHttp)+RxJava 를 사용 합 니 다.
Retrofit 의 Gzip 압축 은 본질 적 으로 OKHttp 의 차단 기 를 통 해 이 루어 진다.
0 차단 요청
1 헤더 추가
2 압축 요청
3 발송
해결 하 다
https://github.com/square/okhttp/wiki/Interceptors
/** This interceptor compresses the HTTP request body. Many webservers can't handle this! */
final class GzipRequestInterceptor implements Interceptor {
@Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
return chain.proceed(originalRequest);
}
Request compressedRequest = originalRequest.newBuilder()
.header("Content-Encoding", "gzip")
.method(originalRequest.method(), gzip(originalRequest.body()))
.build();
return chain.proceed(compressedRequest);
}
private RequestBody gzip(final RequestBody body) {
return new RequestBody() {
@Override public MediaType contentType() {
return body.contentType();
}
@Override public long contentLength() {
return -1; // We don't know the compressed length in advance!
}
@Override public void writeTo(BufferedSink sink) throws IOException {
BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
body.writeTo(gzipSink);
gzipSink.close();
}
};
}
}
7.패키지 비교 요청나 는 우리 가 실제 얼마나 큰 데 이 터 를 전 송 했 는 지 알 수 있 도록 Fiddler 4 로 전체 요청 과정 을 모니터링 할 것 이다.
올 린 구체 적 인 코드 는 보 내지 않 습 니 다.이것 은 중요 한 것 이 아 닙 니 다.
나 는 가방 을 잡 은 후에 request 이것 을 저장 했다.
두 장의 사진 을 동시에 올 리 는 크기 입 니 다.
파일 이름
요청 체 크기
WebP+Gzip
169kb
WebP
222kb
Gzip 으로 압축 하 는 것 이 Gzip 을 넣 지 않 는 것 보다 23%작 습 니 다!jpg 는 보 내지 않 겠 습 니 다.앞에서 계산 해 보 세 요~
WebP 는 Jpg 보다 27%작 고 gzip+webp 는 단순 한 webp 보다 23%작 으 며 절 약 된 데이터 가 얼마나 많은 가!
8.마지막
WebP 는 기본적으로 안 드 로 이 드 4.0 이상 만 지원 하 며,현재 프로젝트 의 최저 지원 버 전 은 16 이기 때문에 문제 가 없습니다.만약 당신 의 프로젝트 가 최소 2.0 까지 지원 해 야 한다 면 제3자 의 지원 도 있 는 것 같 지만,나 는 당신 이 제품 을 잡 아 나 가서 한 대 때 리 는 것 을 건의 합 니 다.
우리 프로젝트 에서 iOS 는 이 기술 을 사용 하지 않 았 다.
아래 의 참고 링크 의 데이터 와 제 가 테스트 한 데 이 터 를 보면 WebP 는 사용자 의 데 이 터 를 크게 절약 할 뿐만 아니 라 이미지 전송 속도 도 가속 화 할 수 있 습 니 다.사진 전송의 측면 에서 볼 때 매우 유리 하 다.
"IOS 못 해,안 해.""백 스테이지 XXX 는 안 해 요."
나 는 네가 제품 을 잡 고 나 가서 한 대 때 릴 것 을 건의 한다.
관련 참고:
http://isux.tencent.com/introduction-of-webp.html(제품 매니저 이거 봐 요)
http://blog.csdn.net/GeekLei/article/details/41147479(백 스테이지 에서 이것 을 봐 야 한다)
https://developers.google.com/speed/webp/
http://www.infoq.com/cn/articles/sdk-optimazation?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term.
http://blog.csdn.net/mingchunhu/article/details/8155742(안 드 로 이 드 는 모두 봐 야 합 니 다)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.