Я работаю над приложением для Android, которое отображает фотографии, загруженные с Flickr. Я получаю растровый объект из байтового массива, который, в свою очередь, читается из соответствующего URL-адреса Flickr следующим образом:
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 объекта View:
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(bitmap, 0, 0, paint);
Проблема в том, что результирующее изображение является пиксельным, и я не могу понять, почему; Я попытался несколько вариантов объектов и рисовать без удачи. Разница между изображением, отображаемым в моем приложении, и изображением с исходным URL-адресом примерно демонстрируется следующим:
Плохое изображение, см. Пикселирование в верхнем левом углу http://homepages.inf.ed.ac.uk/s0677975/bad.jpg
Хорошая картина, это ожидаемый результат http://homepages.inf.ed.ac.uk/s0677975/good.jpg
Смотри, например, на облака в верхнем левом углу, чтобы увидеть разницу.
Обратите внимание, что изображения в формате JPEG, загруженные из ресурсов проекта и отрисованные аналогичным образом, отображаются очень хорошо, то есть не имеют пикселизации.
Кто-нибудь может дать мне подсказку о том, почему это происходит?
Для уточнения, байтовый массив получен из Flickr следующим образом; это основано на коде из приложения Photostream от 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();
PS: Я также разместил вариант этого вопроса в группе Google android.developer.
Большое спасибо за ваше предложение - теперь я действительно озадачен! Я сделал, как вы предложили, и обнаружил, что изображение, полученное непосредственно из загруженного массива байтов, действительно имеет пикселизацию. Тем не менее, он загружается с точно такого же URL-адреса, который, при обращении к нему на моем компьютере, НЕ является пиксельным. Вот соответствующий URL Flickr:
http://farm3.static.flickr.com/2678/4315351421_54e8cdb8e5.jpg
Даже странно, что когда я запускаю одно и то же приложение в симуляторе, а не на телефоне (HTC Hero), пикселизация отсутствует.
Как, черт возьми, это возможно?
Ниже приведен код, который я использую для загрузки растрового изображения из URL - он основан на приложении Photostream от Romain Guy и включает предложение Уилла записать необработанный байтовый массив в файл:
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);
}
}
}
Я схожу с ума здесь?
Лучший,
Майкл.