Skip to content

Instantly share code, notes, and snippets.

@tfcporciuncula
Last active March 19, 2024 11:50
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tfcporciuncula/7aa2b59ccfaa482d1af019868c9a7f63 to your computer and use it in GitHub Desktop.
Save tfcporciuncula/7aa2b59ccfaa482d1af019868c9a7f63 to your computer and use it in GitHub Desktop.
PDF rendering the easy way
<?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"
/>
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))
}
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)
}
}
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
}
@axelbrians
Copy link

Thank you for this code, really help me a lot.

@samsadch
Copy link

samsadch commented Dec 7, 2022

Can we add annotations using PdfRenderer

@varshabhatia007
Copy link

Where this renderSinglePage method is used?

@wendellq89
Copy link

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