Last active
March 19, 2024 11:50
PDF rendering the easy way
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<ImageView | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
android:id="@+id/imageView" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginVertical="8dp" | |
android:importantForAccessibility="no" | |
android:scaleType="fitCenter" | |
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PdfAdapter( | |
// this would come from the ViewModel so we don't need to recreate it on config change | |
// and the VM can close it within onCleared() | |
private val renderer: PdfRenderer, | |
// this would come from the Activity/Fragment based on the display metrics | |
private val pageWidth: Int | |
) : RecyclerView.Adapter<PdfAdapter.ViewHolder>() { | |
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { | |
fun bind(bitmap: Bitmap) = (itemView as ImageView).setImageBitmap(bitmap) | |
} | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = | |
ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.pdf_page_item, parent, false)) | |
override fun getItemCount() = renderer.pageCount | |
override fun onBindViewHolder(holder: ViewHolder, position: Int) = | |
holder.bind(renderer.openPage(position).renderAndClose(pageWidth)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
suspend fun renderSinglePage(filePath: String, width: Int) = withContext(Dispatchers.IO) { | |
PdfRenderer(ParcelFileDescriptor.open(File(filePath), ParcelFileDescriptor.MODE_READ_ONLY)).use { renderer -> | |
renderer.openPage(0).renderAndClose(width) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun PdfRenderer.Page.renderAndClose(width: Int) = use { | |
val bitmap = createBitmap(width) | |
render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY) | |
bitmap | |
} | |
private fun PdfRenderer.Page.createBitmap(bitmapWidth: Int): Bitmap { | |
val bitmap = Bitmap.createBitmap( | |
bitmapWidth, (bitmapWidth.toFloat() / width * height).toInt(), Bitmap.Config.ARGB_8888 | |
) | |
val canvas = Canvas(bitmap) | |
canvas.drawColor(Color.WHITE) | |
canvas.drawBitmap(bitmap, 0f, 0f, null) | |
return bitmap | |
} |
Can we add annotations using PdfRenderer
Where this renderSinglePage method is used?
How to render pdf with clickable links?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for this code, really help me a lot.