#android #image #kotlin #canvas #bitmap
#Android #изображение #kotlin #холст #растровое изображение
Вопрос:
Я создаю базовую медиа-библиотеку, и одной из функций является аннотация изображения. Я получаю медиафайл из системы хранения Android, а затем преобразую его в растровое изображение. Затем я создаю холст из растрового изображения и использую функцию DrawLine класса canvas, чтобы разрешить базовую аннотацию. Проблема, с которой я сейчас сталкиваюсь, заключается в том, что холст и изображение имеют разный размер, поэтому линии нарисованы в неправильном месте.
Это код для создания растровых изображений.
val bmpFactoryOptions = BitmapFactory.Options()
bmpFactoryOptions.inJustDecodeBounds = false
bmp = (BitmapFactory.decodeFile(it.mediaUrl)).rotate(270f)
alteredBitmap = Bitmap.createBitmap(
bmp!!.width, bmp!!
.height, bmp!!.config
)
Затем я создаю объекты canvas, paint и matrix.
canvas = Canvas(alteredBitmap!!)
paint = Paint()
paint!!.color = Color.GREEN
paint!!.strokeWidth = 5f
matrix = Matrix()
canvas!!.drawBitmap(bmp!!, matrix!!, paint)
Затем я устанавливаю alteredBitmap как изображение представления изображения
annotateIV!!.setImageBitmap(alteredBitmap)
Последнее место, где ошибка имела бы смысл, находится в TouchListener ImageView.
annotateIV!!.setOnTouchListener { view, motionEvent ->
when (motionEvent.action) {
ACTION_DOWN -> {
downx = motionEvent.x
downy = motionEvent.y
}
ACTION_MOVE -> {
upx = motionEvent.x
upy = motionEvent.y
canvas!!.drawLine(downx, downy, upx, upy, paint!!)
annotateIV!!.invalidate()
downx = upx
downy = upy
}
ACTION_UP -> {
upx = motionEvent.x
upy = motionEvent.y
canvas!!.drawLine(downx, downy, upx, upy, paint!!)
annotateIV!!.invalidate()
}
ACTION_CANCEL -> {
}
else -> {
}
}
return@setOnTouchListener true
}
Я пытался создать растровое изображение по-разному, но постоянно сталкивался с одной и той же ошибкой масштабирования.
Пример изображения ошибки
Обратите внимание на линии, нарисованные вверху слева. Они были созданы при попытке рисования по всему экрану.
Спасибо всем, кто посмотрел, и любая помощь будет высоко оценена.
Внесены изменения в создание растрового изображения. Это приводит к увеличению изображения, но линии, по крайней мере, нарисованы в правильном месте
bmp = (BitmapFactory.decodeFile(it.mediaUrl)).rotate(270f)
alteredBitmap = Bitmap.createBitmap(
bmp!!.width, bmp!!
.height, bmp!!.config
)
alteredBitmap = Bitmap.createScaledBitmap(alteredBitmap!!, annotateIV.width, annotateIV.height, false)
Ответ №1:
ваш Canvas
размер Bitmap
, вероятно, намного больше, чем размер вашего экрана. вы устанавливаете Bitmap
значение annotateIV
, которое, как я полагаю ImageView
, и scaleType
настроено для подгонки всего Bitmap
внутреннего вида. на самом деле это все еще не изменяет размер Bitmap
/ Canvas
, это просто «предварительный просмотр»
для исправления этого вам следует масштабировать свой Bitmap
размер до размера ImageView
или сделать некоторое значение коэффициента / отношения bitmapSize / imageViewSize и умножить все motionEvent.x
и motionEvent.y
на него
кстати. вызов invalidate()
при каждом MotionEvent
появлении неэффективен … вот почему ваша линия не закруглена, она явно сделана прямыми линиями
Комментарии:
1. alteredBitmap = Bitmap.CreateBitmap(annotateIV.width, annotateIV.height, bmp !!.config ) Я изменил создание растрового изображения на это, теперь изображение сильно увеличено, но линии нарисованы в правильной области на экране. Не могли бы вы уточнить, что вы подразумеваете под последней частью своего сообщения, если это возможно. Большое вам спасибо
2. о
invalidate()
чем? вы вызываете этот метод с каждым новымMotionEvent
, но для рисования требуется время. каждый следующийinvalidate
вызов во время предыдущего запуска просто пропускается, поскольку пользовательский интерфейс зависает на предыдущей операции, поэтому вы теряете некоторые точки для рисования — это хорошо видно в нижней части вашей зеленой линии, она сделана с несколькими прямыми линиями («точки соединены»), не округляется, как при перемещении пальцаэкран3. извините за изменение размера растрового изображения и / или использование соотношения для событий движения. Как бы я это реализовал? Я попытался использовать createScaledBitmap, это привело к увеличению изображения, но, по крайней мере, линии были нарисованы в правильном месте.
4. но для недействительности, как часто вы бы рекомендовали его вызывать?
5. загрузите свой
Bitmap
, как и раньше, но сразу после этого используйтеBitmap.createScaledBitmap
метод и масштабируйте его до размераImageView
. используяBitmap.createBitmap( annotateIV.width, annotateIV.height,...
, вы загружаете только частьBitmap
, которая, установленная наImageView
, выглядит как увеличенная