Класс Android PdfRenderer создает изображения низкого качества
Я использую PdfRenderer
выше api 21 для отображения pdf в моем приложении, и я заметил, что качество страниц очень плохое.
Я также использовал образец Google для использования PdfRenderer
, и вот как я создаю Bitmap
для страницы:
//mCurrentPage is a PdfRenderer.Page and mImageView is an ImageView
Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(),
mCurrentPage.getHeight(),
Bitmap.Config.ARGB_8888);
mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
mImageView.setImageBitmap(bitmap);
Я использовал ARGB_8888
, потому что, насколько я знаю, это лучшее качество для отображения растровых изображений.
Я что-то делаю неправильно?
ИЗМЕНИТЬ
Это огромная разница между классом PdfRenderer и классическим читателем Pdf:
![введите описание изображения здесь]()
Ответы
Ответ 1
ARGB_8888` предназначен только для качества цвета, но качество печати/отображения связано с разрешением (количество точек на дюйм, которое вы показываете на экране).
Например, если у вас есть 400 DPI-экран (400 точек на дюйм) и вы хотите отображать PDF с этим качеством, тогда вы должны отображать растровое изображение через Bitmap.createBitmap(), которое принимает пиксели в виде его размеров:
Bitmap bitmap = Bitmap.createBitmap(
getResources().getDisplayMetrics().densityDpi * mCurrentPage.getWidth() / 72,
getResources().getDisplayMetrics().densityDpi * mCurrentPage.getHeight() / 72,
Bitmap.Config.ARGB_8888
);
где:
-
getResources().getDisplayMetrics().densityDpi
- целевое разрешение DPI
-
mCurrentPage.getWidth()
возвращает ширину в точках Postscript, где каждый pt
равен 1/72 дюйма.
- 72 (DPI) - разрешение по умолчанию PDF.
Следовательно, дайвинг №2 на 72 мы получаем дюймы и умножаем на DPI, мы получаем пиксели. Другими словами, чтобы соответствовать качеству устройства печати на дисплее, вы должны увеличить размер изображения, созданного по умолчанию, разрешение по умолчанию - 72 DPI. Также проверьте этот пост?
Ответ 2
Я немного опоздал. Отмеченный ответ не помог мне, потому что растровое изображение стало большим, и, таким образом, его нельзя было воспроизвести. Я нашел оригинальный пост, потому что у меня была точно такая же проблема, возможно, этот ответ поможет другим в моей ситуации.
Я искал вокруг, чтобы увидеть, есть ли у кого-нибудь аккуратное решение для масштабирования растрового изображения при сохранении соотношения. Я наткнулся на этот сайт:
https://guides.codepath.com/android/Working-with-the-ImageView#scaling-a-bitmap
Это не сложная штука, правда. Мне понадобились только две дополнительные строки кода:
int height = DeviceDimensionsHelper.getDisplayHeight(this);
Bitmap scaledBitmap = BitmapUtil.scaleToFitHeight(bitmap, height);
Я добавил аналогичные классы хелпера/утилит, которые предлагает сайт (так что на практике это более двух строк;)). Высота исходит от
context.getResources().getDisplayMetrics().widthPixels;
Масштабирование просто делит высоту устройства на исходную высоту растрового изображения, чтобы получить коэффициент, который, в свою очередь, умножается на исходную ширину растрового изображения, чтобы найти масштабированную ширину.
Это отлично работает на моем Nexus 5. Я не смог протестировать это на нескольких устройствах, но это кажется надежным решением.
Ответ 3
Вы можете попробовать этот образец с помощью класса PDFViewer
, не уверен в качестве, потому что я никогда не использовал его, но он по-прежнему попробуйте:)
Ответ 4
Как и в случае с PdfRenderer
вы будете отображать страницы PDF в ImageView, проще всего просто создать растровое изображение максимального размера вашего ImageView, добавив некоторые математические выражения для сохранения пропорций PDF. Поскольку PDF обычно предназначены для печати, они всегда будут иметь более высокое разрешение, чем ваш экран, поэтому вы не рискуете получить пиксельное изображение. Чтобы быть уверенным, что для ImageView
ему назначены measuredWidth
ImageView
и measuredHeight
высота, используйте ImageView::post()
в своем коде (извините, мой Котлин):
pdfPageImageView.post {
val viewWidth = pdfPageImageView.measuredWidth
val viewHeight = pdfPageImageView.measuredHeight
val pageWidth = page.width
val pageHeight = page.height
val pageRatio = 1.0 * pageWidth / pageHeight
val viewRatio = 1.0 * viewWidth / viewHeight
val bitmapWidth: Int
val bitmapHeight: Int
if (pageRatio > viewRatio) {
bitmapWidth = viewWidth
bitmapHeight = (viewWidth / pageRatio).toInt()
} else {
bitmapHeight = viewHeight
bitmapWidth = (viewHeight * pageRatio).toInt()
}
val bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888)
page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
pdfPageImageView.setImageBitmap(bitmap)
}