안 드 로 이 드 사진 압축 의 튜 닝 을 한 번 기억 해 주세요.

필요 한 배경: 안 드 로 이 드 패드 (webApp) 에서 사진 캐 시 로 컬 을 찍 고 이미지 base 64 를 서버 에 업로드 합 니 다.문제 발생: 호출 형식 은 모두 전단 에서 원생 껍질 을 호출 하 는 방법 이기 때문에 JS 다리 (자사 가 실현 하 는 안 드 로 이 드, js 상호작용 방법) 를 걸 어야 합 니 다. JS 다 리 를 걸 을 때 원생 보다 느 립 니 다. 그리고 찍 은 사진 을 처리 하지 않 으 면 Base 64 (그림 이 클 수록 Base 64) 를 전단 으로 돌 릴 때 JS 다 리 는 걸 려 서 되 돌 릴 수 없습니다.
머리말 에서 이번 변조 의 배경 이다. 그리고 인터넷 에서 사진 압축 을 검색 하여 품질 압축 과 사이즈 압축 으로 나 누 었 다. 품질 압축 과 사이즈 압축 의 차 이 는 다음 과 같다.
질량 압축
알고리즘 을 통 해 그림 의 특정한 점 근처에 있 는 픽 셀 을 잠 그 고 품질 을 낮 추어 파일 크기 를 줄 이 는 목적 을 달성 했다.여기 서 주의해 야 할 것 은 이렇게 압축 된 그림 자체 의 픽 셀 너비 와 높이 는 변 하지 않 지만 그림 파일 의 크기 는 확실히 작 아 지기 때문에 Base 64 길이 도 짧 아 집 니 다. 그러면 원칙적으로 품질 압축 으로 제 요 구 를 만족 시 킬 수 있 습 니 다.그러나 만약 에 제 가 원래 이 그림 을 사용 해 야 한다 면 똑 같은 메모 리 를 사용 할 것 입 니 다. 원생 이 사용 하면 bitmap 형식 으로 표시 할 것 입 니 다. bitmap 가 메모리 에 대한 점용 은 그림 픽 셀 에 따라 계 산 됩 니 다.
사이즈 압축
이 압축 은 그림 의 픽 셀 값 을 실질 적 으로 줄 이 는 것 이다.
상기 두 가 지 를 결합 하면 나 는 최종 적 으로 두 가 지 를 결합 하 는 방식 으로 이 수 요 를 실현 하기 로 결정 했다.먼저 사이즈 압축 을 하고 목표 크기 로 압축 한 다음 에 품질 압축 을 해서 Base 64 길 이 를 줄 입 니 다.
최종 적 으로 저 는 사이즈 에 따라 1M 정도 이하 로 압축 하고 품질 은 100 K 이하 로 압축 합 니 다. 코드 는 다음 과 같 습 니 다.
/**
     *         +     (              ,              )
     *
     * @param ref                 KB    ref1                KB   
     */
    private String dimensionCompress(File file, long ref,int ref1) {
        long length = file.length() / 1024;
        String result = "";
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//   true  ,        ,     bitmap null
        BitmapFactory.decodeFile(file.getAbsolutePath(), options);
        int inSampleSize = 2;//       ,     。
        if (length > ref) { //                     px
            float ratio = (float) length / ref; //         
            inSampleSize = (int) ratio;
        }
        options.inJustDecodeBounds = false; //         ,          
        options.inSampleSize = inSampleSize;
        Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options); //     

        BufferedOutputStream bos = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        int quality = 100;
        try {
            if (bitmap != null) {
                byteArrayOutputStream = new ByteArrayOutputStream();
                bos = new BufferedOutputStream(byteArrayOutputStream);
                bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
                if(byteArrayOutputStream.toByteArray().length/1024>ref1){
                    quality = 100*ref1/(byteArrayOutputStream.toByteArray().length/1024);
                    byteArrayOutputStream.reset();
                    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
                }
                bos.flush();
                bos.close();
                byteArrayOutputStream.flush();
                byteArrayOutputStream.close();
                byte[] bitmapBytes = byteArrayOutputStream.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.NO_WRAP);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bos != null) {
                    bos.flush();
                    bos.close();
                }
                if (byteArrayOutputStream != null) {
                    byteArrayOutputStream.flush();
                    byteArrayOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

이 방법 을 쓸 때 나 는 BitmapFactory. decodeFile 방법 을 한 번 호출 하 는 데 200 ms 정도 의 시간 이 필요 하 다 는 것 을 알 게 되 었 다. 느낌 이 좀 길 었 다. 더 좋 은 방법 이 있다 면 누군가가 나 에 게 알려 주 기 를 바란다.업무 장면 이 복잡 하기 때문에 시간 을 최대한 줄 이 는 취지 에 따라 저 는 먼저 목표 의 크기 에 따라 제 가 몇 배 정도 압축 해 야 하 는 지 계산 한 다음 에 한 번 만 압축 하 는 것 입 니 다. 인터넷 의 목표 픽 셀 너비 에 따라 여러 번 압축 하 는 것 이 아 닙 니 다.또한, 여기 서 주의해 야 할 것 은 options. inSampleSize 라 는 값 은 영원히 2 의 배수 로 계산 하 는 것 입 니 다. 예 를 들 어 9 를 설정 하면 그 는 8 (2 의 3 차원) 에 따라 계산 할 것 입 니 다.품질 압축 의 목표 치 에 대해 제 가 설정 한 100 K 는 다음 과 같은 고려 를 바탕 으로 합 니 다. 사이즈 압축 을 한 후의 그림 크기 는 1M 보다 크 지 않 을 것 입 니 다. 그러면 품질 압축 률 은 90% 보다 크 지 않 을 것 입 니 다. 마지막 으로 바닥 을 남 겨 서 일 그 러 짐 률 을 확보 하 세 요.
이로써 이번 조정 은 끝 났 습 니 다. 한 번 호출 하 는 방법 은 800 ms 가 되 지 않 았 습 니 다. 이것 은 나중에 방법 을 찾 아 최적화 할 수 있 습 니 다. 다음 에 다시 오 겠 습 니 다.
2019018 수정 테스트 를 통 해 그 내용 이 비교적 많은 사진, 예 를 들 어 찍 은 엑셀 의 사진 (안에 모두 문자 데이터 정보), 한도 값 을 1M, 100 K 로 설정 하면 심각 한 일 그 러 짐 을 초래 할 수 있다. 나중에 3000 K, 1000 K 로 설정 할 때 이런 그림 이 든 다른 그림 이 든 모두 정상적으로 표 시 될 수 있다.그래서 현 재 는 한도 값 을 바 꾸 었 기 때문에 계속 연구 하고 개선 할 수 밖 에 없다.

좋은 웹페이지 즐겨찾기