Estoy trabajando en una aplicación de Android que muestra fotos que se descargan desde Flickr. Puedo obtener un objeto de mapa de bits a partir de una matriz de bytes, que a su vez se lee de la URL correspondiente Flickr, de la siguiente manera:Android: BitmapFactory.decodeByteArray da bitmap pixelado
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inDither = true;
opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opt);
entonces dibujar el mapa de bits en un lienzo en el método onDraw de un objeto View:
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(bitmap, 0, 0, paint);
El problema es que la imagen resultante está pixelada y no puedo entender por qué; He intentado varias variaciones de los objetos de opt y paint sin suerte. La diferencia entre la imagen que aparece en mi aplicación y la imagen en la dirección URL original es más o menos lo demuestra el siguiente:
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
Mira, por ejemplo, en las nubes en la esquina superior izquierda para ver la diferencia.
Tenga en cuenta que las imágenes JPEG que se cargan desde los recursos del proyecto y se dibujan de manera similar se muestran bien, es decir, no tienen pixelación.
¿Alguien puede darme una pista de por qué está sucediendo esto?
Para elaborar un poco, la matriz de bytes se obtiene de Flickr de la siguiente manera; esto se basa en el código de la aplicación Secuencia de fotos de Romain Guy:
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();
PD: También he publicado una variante de esta cuestión en el grupo de Google android.developer.
Muchas gracias por su sugerencia - ¡Ahora estoy realmente perplejo! Hice lo que sugirió y descubrí que la imagen resultante directamente de la matriz de bytes descargada está efectivamente pixelada. Sin embargo, esto se descarga desde exactamente la misma URL que, cuando se accede desde mi computadora, NO está pixelada. Aquí está la URL correspondiente Flickr:
http://farm3.static.flickr.com/2678/4315351421_54e8cdb8e5.jpg
Aún más extraño, cuando corro la misma aplicación en el simulador y no en mi teléfono (un HTC Hero), no hay ninguna pixelación.
¿Cómo es esto posible?
A continuación se muestra el código que utilizo para cargar un mapa de bits de una dirección URL - que se basa en la aplicación Secuencia de fotos de Romain individuo, e incorpora la sugerencia de Will para escribir la matriz de bytes sin procesar en el archivo:
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);
}
}
}
¿Me estoy volviendo loco aquí? Mejor, Michael.
Me tomé la libertad de subrayar las imágenes, ya que por lo general la pregunta es más clara y fácil de leer. – unwind
¿Alguna vez encontró una solución para esto? Probé las sugerencias, pero no tuve suerte. Es súper molesto – blork
como nota al pie, no olvide que JPEG no tiene pérdida en el entorno de Android. aunque es compatible, se desaconseja a favor de PNG. – user836725