У меня возникают проблемы при использовании ScriptIntrinsicYuvToRGB из библиотеки поддержки для преобразования изображений из формата NV21 в Bitmaps (ARGB_8888). Приведенный ниже код может проиллюстрировать проблему.Поврежденные изображения при использовании ScriptIntrinsicYuvToRGB (поддержка lib) для NV21 в Bitmap
Пусть у меня есть следующие 50х50 изображения (ниже один скриншот из устройства, а не на самом деле 50х50):
Тогда, если я конвертировать указанное изображение в Bitmap через YuvImage#compressToJpeg
+ BitmapFactory.decodeByteArray
:
YuvImage yuvImage = new YuvImage(example, android.graphics.ImageFormat.NV21, width, height, null);
ByteArrayOutputStream os = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, os);
byte[] jpegByteArray = os.toByteArray();
return BitmapFactory.decodeByteArray(jpegByteArray, 0, jpegByteArray.length);
Я получаю ожидаемое изображение. Но если преобразовать его через ScriptIntrinsicYuvToRGB следующим образом:
RenderScript rs = RenderScript.create(context);
Type.Builder tb = new Type.Builder(rs, Element.createPixel(rs,
Element.DataType.UNSIGNED_8, Element.DataKind.PIXEL_YUV));
tb.setX(width);
tb.setY(height);
tb.setYuvFormat(android.graphics.ImageFormat.NV21);
Allocation yuvAllocation = Allocation.createTyped(rs, tb.create(), Allocation.USAGE_SCRIPT);
yuvAllocation.copyFrom(example);
Type rgbType = Type.createXY(rs, Element.RGBA_8888(rs), width, height);
Allocation rgbAllocation = Allocation.createTyped(rs, rgbType);
ScriptIntrinsicYuvToRGB yuvToRgbScript = ScriptIntrinsicYuvToRGB.create(rs, Element.RGBA_8888(rs));
yuvToRgbScript.setInput(yuvAllocation);
yuvToRgbScript.forEach(rgbAllocation);
Bitmap convertedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
rgbAllocation.copyTo(convertedBitmap);
Я получаю следующее поврежденное изображение:
Я заметил, что это не происходит с изображениями квадратных размеров и никогда с силами 2 (например, 64x64, 128x128 и т. д.). Если бы я не пробовал квадратные размеры, я бы не заметил эту проблему, так как некоторые размеры изображения, такие как 2592x1728, работают нормально. Что мне не хватает?
Update: ввод кода, который сгенерировал исходное изображение в соответствии с просьбой:
int width = 50;
int height = 50;
int size = width * height;
byte[] example = new byte[size + size/2];
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
example[y * width + x] = (byte) ((x*y/(float)size) * 255);
}
}
for (int i = 0; i < size/2; i++) {
example[size + i] = (byte) (127);
}
Вы можете разместить файл ввода, который может быть использован для тестирования кода? В противном случае немного сложно воспроизвести ошибку. :) – cmaster11
@ cmaster11 Я сделал это лучше, я просто добавил код, который сгенерировал входное изображение в конце вопроса :) – silvaren