Android 는 그림 압축(bitmap 의 6 가지 압축 방식)을 실현 합 니 다.

Android 에서 그림 은 bitmap 형식 으로 존재 합 니 다.그러면 bitmap 가 차지 하 는 메모리 가 응용 프로그램 이 차지 하 는 메모리 크기 에 직접적인 영향 을 줍 니 다.먼저 bitmap 가 차지 하 는 메모리 크기 계산 방식 을 알 아야 합 니 다.
그림 길이 x 그림 너비 x 픽 셀 점 이 차지 하 는 바이트 수
다음은 그림 의 압축 형식 입 니 다.
这里写图片描述
그 중에서 A 는 투명 도 를 나타 낸다.R 은 빨간색 을 나타 낸다.G 는 녹색 을 대표 합 니 다.B 는 파란색 을 대표 합 니 다.
ALPHA_8
8 비트 알파 비트 맵,즉 A=8 을 표시 합 니 다.픽 셀 점 하나 가 1 바이트 를 차지 합 니 다.색상 이 없고 투명도 만 있 습 니 다.
ARGB_4444
16 비트 ARGB 비트 맵,즉 A=4,R=4,G=4,B=4 를 나타 내 며 하나의 픽 셀 점 이 4+4+4+4=16 비트,2 바이트 를 차지한다.
ARGB_8888
32 비트 ARGB 비트 맵,즉 A=8,R=8,G=8,B=8 을 나타 내 고 하나의 픽 셀 점 은 8+8+8+8=32 비트,4 바이트 입 니 다.
RGB_565
16 비트 RGB 비트 맵,즉 R=5,G=6,B=5 를 표시 합 니 다.투명 성 이 없고 픽 셀 점 이 5+6+5=16 비트,2 바이트 입 니 다.
저 는 샤 오미 핸드폰 2s 로 테스트 를 했 습 니 다.sd 카드 에서 사진 하 나 를 꺼 냈 습 니 다.다음 과 같 습 니 다.

bit = BitmapFactory.decodeFile(Environment
        .getExternalStorageDirectory().getAbsolutePath()
        + "/DCIM/Camera/test.jpg");

    Log.i("wechat", "        " + (bit.getByteCount() / 1024 / 1024)
        + "M   " + bit.getWidth() + "   " + bit.getHeight());
나 온 log 는:
这里写图片描述
얻 은 bitmap 를 압축 합 니 다.다음은 bitmap 의 몇 가지 압축 방식 을 말 합 니 다.
1.품질 압축

      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      int quality = Integer.valueOf(editText.getText().toString());
      bit.compress(CompressFormat.JPEG, quality, baos);
      byte[] bytes = baos.toByteArray();
      bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
      Log.i("wechat", "        " + (bm.getByteCount() / 1024 / 1024)
          + "M   " + bm.getWidth() + "   " + bm.getHeight()
          + "bytes.length= " + (bytes.length / 1024) + "KB"
          + "quality=" + quality);
그 중에서 quality 는 editext 에서 얻 은 숫자 로 0C 100 에서 바 꿀 수 있 습 니 다.여기 서 나 온 log 는:
这里写图片描述
그림 의 크기 는 변 하지 않 았 다.품질 압축 은 그림 의 픽 셀 을 줄 이지 않 기 때문에 픽 셀 을 유지 하 는 전제 에서 그림 의 깊이 와 투명 도 를 바 꾸 는 등 그림 을 압축 하 는 목적 을 달성 하 는 것 도 이 방법 을 품질 압축 방법 이 라 고 부 르 는 이유 이다.그러면 그림 의 길이,너비,픽 셀 이 변 하지 않 으 면 bitmap 가 차지 하 는 메모리 크기 는 변 하지 않 습 니 다.
그러나 우 리 는 bytes.length 가 퀄 리 티 가 작 아 지면 서 작 아 지 는 것 을 보 았 다.이렇게 하면 바 이 너 리 의 그림 데 이 터 를 전달 하 는 데 적합 하 다.예 를 들 어 위 챗 이 그림 을 공유 할 때 바 이 너 리 데 이 터 를 과거 에 전송 하고 32kb 안에 제한 해 야 한다.
bit.copress(CompressFormat.PNG,quality,baos)라면이러한 png 형식 은 quality 가 작용 하지 않 습 니 다.bytes.length 는 변 하지 않 습 니 다.png 그림 은 손상 이 없 기 때문에 압축 할 수 없습니다.
CompressFormat 의 또 다른 속성 은 CompressFormat.WEBP 형식 입 니 다.이 형식 은 구 글 이 스스로 그림 형식 을 밀어 내 고 더 많은 정 보 를 보 내 며 마지막 에 주 소 를 붙 입 니 다.
2.샘플링 압축

BitmapFactory.Options options = new BitmapFactory.Options();
      options.inSampleSize = 2;

      bm = BitmapFactory.decodeFile(Environment
          .getExternalStorageDirectory().getAbsolutePath()
          + "/DCIM/Camera/test.jpg", options);
      Log.i("wechat", "        " + (bm.getByteCount() / 1024 / 1024)
          + "M   " + bm.getWidth() + "   " + bm.getHeight());

로그 가 나 왔어요.
这里写图片描述
inSampleSize 의 값(int 형식)을 설정 한 후 2 로 설정 하면 너비 와 높이 가 원래 의 1/2 이 고 너비 와 높이 가 모두 감소 하 며 자연 메모리 도 낮 아 집 니 다.
내 위의 코드 는 options.inJustDecodeBounds=true 를 사용 한 적 이 없다.저 는 고정 적 으로 표본 을 추출 하 는 데이터 이기 때문에 이 압축 방법 을 샘플링 율 압축 이 라 고 하 는 이 유 는 inJustDecodeBounds 와 결합 하여 먼저 그림 의 너비,높이 를 얻 은 다음 에 얻 은 너비,높이,동적 으로 inSampleSize 의 값 을 설정 하기 때 문 입 니 다.
inJustDecodeBounds 가 true 로 설정 되 었 을 때 BitmapFactory 는 decodeResource 나 decodeFile 을 통 해 그림 을 디 코딩 할 때 빈 Bitmap 대상 을 되 돌려 줍 니 다.이렇게 하면 Bitmap 의 메모리 분 배 를 피 할 수 있 지만 Bitmap 의 너비,높이,MimeType 을 되 돌려 줍 니 다.
3.확대/축소 압축(martix)

Matrix matrix = new Matrix();
      matrix.setScale(0.5f, 0.5f);
      bm = Bitmap.createBitmap(bit, 0, 0, bit.getWidth(),
          bit.getHeight(), matrix, true);
      Log.i("wechat", "        " + (bm.getByteCount() / 1024 / 1024)
          + "M   " + bm.getWidth() + "   " + bm.getHeight());

로그 가 나 왔어요.
这里写图片描述
비트 맵 의 길이 와 너 비 는 각각 반 으로 줄 었 고 그림 의 크기 는 4 분 의 1 로 줄 어 든 것 을 알 수 있다.
martix 에 대한 더 많은 정보 에 대해 서 는 마지막 에 참고 글 이 있 을 것 입 니 다.
4.RGB_565 법

BitmapFactory.Options options2 = new BitmapFactory.Options();
      options2.inPreferredConfig = Bitmap.Config.RGB_565;

      bm = BitmapFactory.decodeFile(Environment
          .getExternalStorageDirectory().getAbsolutePath()
          + "/DCIM/Camera/test.jpg", options2);
      Log.i("wechat", "        " + (bm.getByteCount() / 1024 / 1024)
          + "M   " + bm.getWidth() + "   " + bm.getHeight());

나 온 log 는:
这里写图片描述
우 리 는 그림 의 크기 가 바로 반 으로 줄 어 들 고 길이 와 너비 도 변 하지 않 는 것 을 보 았 다.argb 에 비해8888 은 메모리 의 절반 을 줄 였 다.
주의:ARGB 때문에4444 의 화질 은 끔찍 합 니 다.일반적으로 그림 에 대한 투명 성 요구 가 없 으 면 RGB 로 바 꿀 수 있 습 니 다.565,비교 ARGB8888 은 메모리 비용 의 절반 을 절약 할 것 이다.
5.createScaledBitmap

bm = Bitmap.createScaledBitmap(bit, 150, 150, true);
      Log.i("wechat", "        " + (bm.getByteCount() / 1024) + "KB   "
          + bm.getWidth() + "   " + bm.getHeight());
로그 가 나 왔어요.
这里写图片描述
여 기 는 그림 을 사용자 가 원 하 는 길이 와 너비 로 압축 하 는 것 입 니 다.그러나 여기 서 사용자 가 원 하 는 길이 와 너비 가 원 하 는 길이 와 너비 의 차이 가 너무 많 으 면 그림 이 뚜렷 하지 않 습 니 다.
총결산
이상 은 5 가지 그림 압축 방법 입 니 다.여기 서 강조 할 필요 가 있 습 니 다.그들의 압축 은 안 드 로 이 드 의 bitmap 에 만 있 습 니 다.이 압축 된 bitmap 를 sd 로 저장 하면 메모리 크기 가 다 릅 니 다.
안 드 로 이 드 핸드폰 에서 그림 이 차지 하 는 메모리 크기 는 여러 가지 요소 와 관련 되 어 계산 하기 도 매우 번거롭다.그림 의 메모리 크기 를 계산 하기 위해 서 그림 을 파일 로 간접 적 으로 계산 할 수 있 습 니 다.다음 과 같은 방법 을 사용 하 십시오.

 File file = new File(Environment.getExternalStorageDirectory()
     .getAbsolutePath() + "/DCIM/Camera/test.jpg");
     Log.i("wechat", "file.length()=" + file.length() / 1024);

혹은

FileInputStream fis = null;
    try {
      fis = new FileInputStream(file);
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }
    try {
      Log.i("wechat", "fis.available()=" + fis.available() / 1024);
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

위의 두 가지 방법 으로 계산 한 결 과 는 같다.
이 내용 을 다 읽 었 습 니 다.사실은 Bitmap 압축 은 모두 이것 을 중심 으로 글 을 썼 습 니 다.Bitmap 가 사용 하 는 메모리=그림 길이 x 그림 너비 x 픽 셀 점 에서 사용 하 는 바이트 수 입 니 다.세 개의 매개 변 수 는 한 개의 값 을 임의로 줄 이면 압축 효과 에 도달한다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기