Альтернативы
Если вы находитесь на уровне API 10+, вы можете альтернативно использовать BitmapRegionDecoder
, который выполняет обрезку и понижение частоты дискретизации за один шаг, возможно, на нативном языке.
В качестве совершенно другого подхода вы также можете попробовать преобразовать data
непосредственно в Bitmap
, а затем с помощью Canvas
нарисовать некоторую часть исходного растрового изображения в новой обрезанной версии, выполнив масштабирование с помощью Canvas. матрица преобразования.
качество
изображение должно быть хорошего качества, хорошо и быстро обрезаться.
Ваш первый шаг, когда вы сжимаете до quality=50
, вы теряете много информации. Затем, когда вы создаете новое растровое изображение, вы увеличиваете масштаб, что также влияет на качество; на мой взгляд, обрезка имеет смысл, только если результирующее изображение на самом деле меньше.
Эффективность
Затем мы обрезаем это растровое изображение с помощью метода ниже (это кажется неэффективным в 2018 году)
Подумайте над этим: вам действительно нужно, чтобы точечный размер был точным? Вероятно, гораздо лучше оставить растровое изображение в качестве обрезанного размера, иметь меньший растровое изображение в памяти, загрузить меньшее растровое изображение в графический процессор и позволить масштабированию с помощью рендеринга графического процессора. Возможно, View
не будет соответствовать размеру Bitmap
, поэтому это все равно произойдет.
Glide
Glide в основном делает то же самое, что и ваш код (кроме бита YUV). См. Downsampler
, разница в том, что он работает со многими источниками ввода, форматами и уровнями API, отсюда и разница в размере.
наш основной продукт должен быть максимально легким:)
Включение библиотеки загрузки изображений и принуждение пользователя включить это также противоречит этому. Но в то же время вы действительно хотите заново изобрести колесо и написать свою собственную библиотеку загрузки изображений? Например, у Glide есть много частей, которые можно заменить для пользовательского поведения.
В моем приложении у меня есть камера -> выбор обрезки пользователя -> обрезанный меньший поток растровых изображений. Я сделал что-то похожее на ваше, за исключением использования диска вместо ByteArrayOutputStream
, потому что ввод может быть огромным, и его нужно было бы вдвое увеличить в памяти, на что нет гарантии.