[Android] PdfRenderer

구현모·2023년 4월 20일
0

android

목록 보기
1/1
post-thumbnail

안드로이드를 공부하려고 간단한 pdf 뷰어를 만들어 보다가 안드로이드에서 제공하는 PdfRenderer 클래스를 발견했다.

https://developer.android.com/reference/android/graphics/pdf/PdfRenderer

PdfRenderer

android developers에서는 PDF를 렌더링하는 일반적인 방법을 다음과 같이 설명하고 있다.

 // new renderer
 PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor());

 // let us just render all pages
 final int pageCount = renderer.getPageCount();
 for (int i = 0; i < pageCount; i++) {
     Page page = renderer.openPage(i);

     // say we render for showing on the screen
     page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY);

     // do stuff with the bitmap

     // close the page
     page.close();
 }

 // close the renderer
 renderer.close();

간단한 예제

변수

var imageList: MutableList<ImageBitmap> = mutableListOf()
var pdfUri by remember { mutableStateOf<Uri?>(null) }

PDF uri 얻어오기

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
    addCategory(Intent.CATEGORY_OPENABLE)
    type = "application/pdf"
}

val requestLauncher = rememberLauncherForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) {
    pdfUri = it.data?.data
}

requestLauncher.launch(intent)

PdfRender 생성

val renderer = context.contentResolver.openFileDescriptor(
        pdfUri,
        "r"
    )?.let { PdfRenderer(it) }

PDF의 각 장을 렌더링

for (i in 0 until renderer.pageCount) {
    val page = renderer.openPage(i)
    val bitmap =
        Bitmap.createBitmap(page.width, page.height, Bitmap.Config.ARGB_8888)
    page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
    imageList.add(bitmap.asImageBitmap())
    page.close()
}
renderer.close()

전체 코드

import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.pdf.PdfRenderer
import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext

@Composable
fun PdfViewer(modifier: Modifier = Modifier) {
    var imageList: MutableList<ImageBitmap> = mutableListOf()
    var pdfUri by remember { mutableStateOf<Uri?>(null) }

    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        addCategory(Intent.CATEGORY_OPENABLE)
        type = "application/pdf"
    }

    val requestLauncher = rememberLauncherForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) {
        pdfUri = it.data?.data
    }

    when(pdfUri) {
        null -> {
            Button(onClick = {
                requestLauncher.launch(intent)
            }) {
                Text(text = "PDF 선택")
            }
        }
        else -> {
            pdfLoad(pdfUri!!, imageList, LocalContext.current)
            LazyColumn(modifier.fillMaxSize()) {
                items(imageList) { page ->
                    Image(
                        bitmap = page,
                        contentDescription = null,
                        modifier = modifier.fillMaxSize(),
                        contentScale = ContentScale.Crop
                    )
                }
            }
        }
    }
}

fun pdfLoad(pdfUri: Uri, imageList: MutableList<ImageBitmap>, context: Context) {
    val renderer = context.contentResolver.openFileDescriptor(
        pdfUri,
        "r"
    )?.let { PdfRenderer(it) }

    if (renderer != null) {
        for (i in 0 until renderer.pageCount) {
            val page = renderer.openPage(i)
            val bitmap =
                Bitmap.createBitmap(page.width, page.height, Bitmap.Config.ARGB_8888)
            page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
            imageList.add(bitmap.asImageBitmap())
            page.close()
        }
        renderer.close()
    }
}

Simple PDF Viewer

https://github.com/hmooko/SimpleAndroidPdfViewer-JetpackCompose

profile
단국대학교 소프트웨어학 재학 중이며 모바일 전반에 관심이 있습니다!!

0개의 댓글