2010-02-02 2 views
12

Flickr에서 다운로드 한 사진을 표시하는 Android 앱에서 작업 중입니다. 다음과 같이 나는 다시 관련 플리커 URL에서 읽은 바이트 배열에서 비트 맵 오브젝트를 취득 :Android : BitmapFactory.decodeByteArray는 픽셀 화 된 비트 맵을 제공합니다.

BitmapFactory.Options opt = new BitmapFactory.Options(); 
opt.inDither = true; 
opt.inPreferredConfig = Bitmap.Config.ARGB_8888; 
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opt); 

내가 다음보기 개체의 된 onDraw 방법에 캔버스에 비트 맵을 그릴 :

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); 
canvas.drawBitmap(bitmap, 0, 0, paint); 

문제는 결과로 나타나는 그림이 픽셀 화되어 있고 그 이유를 파악할 수 없다는 것입니다. opt 및 paint 객체의 여러 변형을 행운으로 시도했습니다.

Bad image, see pixelation in top left corner http://homepages.inf.ed.ac.uk/s0677975/bad.jpg

Good picture, this is the expected result http://homepages.inf.ed.ac.uk/s0677975/good.jpg

봐 예 : 내 응용 프로그램에 표시되는 화면과 원래의 URL에서 그림 사이의 차이는 대략 다음에 의해 증명된다 그 차이를보기 위해 왼쪽 상단에있는 구름에.

프로젝트 리소스에서로드되어 비슷한 방식으로 그려진 JPEG 그림은 픽셀이 표시되지 않는 점을 유의하십시오.

아무도 내게 왜 이런 일이 일어날 지에 대한 힌트를 줄 수 있습니까?

조금 더 자세히 설명하기 위해 바이트 배열은 다음과 같이 Flickr에서 가져옵니다. 이것은 로맹 사람에 의해 포토 스트림 응용 프로그램에서 코드를 기반으로합니다 :

InputStream in = new BufferedInputStream(url.openStream(), IO_BUFFER_SIZE); 
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 
out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE); 
copy(in, out); 
out.flush(); 
final byte[] data = dataStream.toByteArray(); 

PS를 : 나는 또한 android.developer 구글 그룹에이 질문의 변형을 기록했다.


제안 해 주셔서 감사합니다. 지금은 정말 당황 스럽습니다. 내가 제안한 바대로 다운로드 한 바이트 배열에서 직접 생성 된 이미지가 실제로 픽셀 화 된 것을 발견했습니다. 그러나이 URL은 내 컴퓨터에서 액세스 할 때 픽셀 화되지 않은 동일한 URL에서 다운로드됩니다. 내가 시뮬레이터보다는 내 전화 (A HTC 영웅)에서 동일한 응용 프로그램을 실행할 때

http://farm3.static.flickr.com/2678/4315351421_54e8cdb8e5.jpg

심지어 낯선 사람이, 어떤 픽셀 레이션이 없다 : 여기에 해당 플리커 URL입니다.

어떻게 가능합니까? 다음은

내가 URL에서 비트 맵을로드하기 위해 사용하는 코드입니다 -이 로맹 사람에 의해 포토 스트림 응용 프로그램을 기반으로, 그것은 파일로 원시 바이트 배열을 작성하는 의지의 제안을 통합 :

Bitmap loadPhotoBitmap(URL url) { 
    Bitmap bitmap = null; 
     InputStream in = null; 
     BufferedOutputStream out = null; 

     try { 

      FileOutputStream fos = new FileOutputStream("/sdcard/photo-tmp.jpg"); 
      BufferedOutputStream bfs = new BufferedOutputStream(fos); 

      in = new BufferedInputStream(url.openStream(), 
        IO_BUFFER_SIZE); 

      final ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 
      out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE); 
      copy(in, out);      
      out.flush(); 
      final byte[] data = dataStream.toByteArray(); 

      bfs.write(data, 0, data.length); 
      bfs.flush(); 

      BitmapFactory.Options opt = new BitmapFactory.Options(); 
      bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opt); 

     } catch (IOException e) { 
      android.util.Log.e(LOG_TAG, "Could not load photo: " + this, e); 
     } finally { 
      closeStream(in); 
      closeStream(out) 
      closeStream(bfs); 
     } 

     return bitmap; 
    } 

private static void copy(InputStream in, OutputStream out) throws IOException { 
    byte[] b = new byte[IO_BUFFER_SIZE]; 
    int read; 
    while ((read = in.read(b)) != -1) { 
     out.write(b, 0, read); 
    } 
} 

private static void closeStream(Closeable stream) { 
    if (stream != null) { 
     try { 
      stream.close(); 
     } catch (IOException e) { 
      android.util.Log.e(LOG_TAG, "Could not close stream", e); 
     } 
    } 
} 

나는 여기서 미쳤어? 최고, 마이클.

+0

이미지를 인라이닝하는 자유를 얻었습니다. 일반적으로 이미지를 더 멋지고 읽기 쉽게 만들어주기 때문입니다. – unwind

+1

이것을 해결할 방법을 찾았습니까? 나는 제안을 시도했지만 운은 없다. 그것은 매우 성가신 일입니다. – blork

+0

을 각주로 사용하십시오. 안드로이드 환경에서는 JPEG이 무손실하지 않다는 것을 잊지 마십시오. 지원되지만 PNG에 찬성하여 낙담합니다. – user836725

답변

3

URL에서 가져온 원시 바이트를 /sdcard/tmp.jpg으로 작성하고 PC에서 봅니다.

JPEG 이미지는 8x8 (또는 16x16) 타일로 압축됩니다. 설명하는 '픽셀 화'는 실제로 이러한 타일에 있으며, '나쁜'이미지가 다른 이미지보다 더 적극적으로 압축 된 JPEG임을 나타냅니다.

실제 문제는 다운로드중인 이미지가 매우 저품질 버전이라는 것입니다. 하나는 미리보기/미리보기 사용 사례를위한 것입니다.

+0

나는이 역시 의심 스럽지만, "나쁜"이미지의 실제 파일 크기는 "좋은"이미지보다 약 18 % * 커졌습니다. 이상한. – unwind

+0

그것도 아무것도 증명하지 않는다. – Will

4

좋아, 결국 얻었습니다. 내 모바일 네트워크가 대역폭을 절약하기 위해 이미지 압축을 수행하는 것처럼 보입니다.

따라서 내 휴대폰에서 다운로드 한 사진은 내 컴퓨터에서 다운로드 한 사진보다 품질이 떨어집니다.

그건 내 앱에 대한 파머이지만, 나는 그것에 대해 할 수있는 일이 없다고 생각한다. 한숨.

의견을 보내 주셔서 다시 한번 감사드립니다.

최고, 마이클.

+0

http 헤더에 의해 메시지가 표시 될 수도있다. 즉, 페이스 북 자체가 휴대폰 용 저품질 이미지를 제공 할 수있다. 보내기 전에 헤더를 편집하십시오 - 기본적으로 모두 제거하십시오! – Will

+1

http 헤더를 Accept-Encoding gzip으로 설정할 수 있습니다. 확신 할 수는 없지만 네트워크 이미지 압축을 사용할 수 있습니다. http://stackoverflow.com/questions/1573391/android-http-communication-should-use-accept-encoding-gzip –

+0

브라우저에서 이미지를 다운로드하여 이것을 확인하려고 했습니까? 나는 동일한 문제가 있지만 웹 브라우저에서 이미지를 열면 unpixelated 이미지가 나타납니다. 올바른 이미지를 얻을 수있는 방법이 있어야합니다. – Janusz

1

일부 Android 버전은 Bitmap 클래스에 버그가있어 일부 작업시 비트 맵을 RGB_565로 변환합니다. 이것은 당신의 그림에있는 유물과 비슷한 유물에서 나타납니다. 이것은 또한 푸른 하늘의 줄무늬를 설명 할 것입니다. 또한 안드로이드는 이미지를로드 할 때 rgb_565로 변환하여 이미지를 "최적화"하려고하며 리소스 파일로 컴파일하려고합니다. 다음을보십시오 : http://android.nakatome.net/2010/04/bitmap-basics.html