Rudimentary thumbnail pixels-based autocrop detection.
A better solution would be using element bounds, but that requires a higher API level so I need a working fallback.
This commit is contained in:
parent
9a2b5ce297
commit
a74ccdcfcb
|
@ -9,7 +9,7 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.lhw.pdf"
|
applicationId = "com.lhw.pdf"
|
||||||
minSdk = 25
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "1.0"
|
versionName = "1.0"
|
||||||
|
|
|
@ -28,51 +28,33 @@ import androidx.core.view.WindowInsetsCompat
|
||||||
import com.lhw.pdf.databinding.ActivityMainBinding
|
import com.lhw.pdf.databinding.ActivityMainBinding
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
|
import java.io.InputStream
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||||
private lateinit var binding: ActivityMainBinding
|
private lateinit var binding: ActivityMainBinding
|
||||||
private lateinit var fileCached: File
|
|
||||||
private lateinit var renderer: PdfRenderer
|
|
||||||
private val thumbnailWidth = 500
|
private val thumbnailWidth = 500
|
||||||
private val thumbnailHeight = 700
|
private val thumbnailHeight = 700
|
||||||
private val bitmapThumbnails = mutableMapOf<Int, Bitmap>()
|
private lateinit var pdfDocument: PdfDocument
|
||||||
// private val bitmapPagesMain = mutableMapOf<Int, Bitmap>()
|
|
||||||
private val bitmapPagesPresentation = mutableMapOf<Int, Bitmap>()
|
|
||||||
private val testPdf = R.raw.testpdf
|
|
||||||
private lateinit var presentationScroll: HorizontalScrollView
|
private lateinit var presentationScroll: HorizontalScrollView
|
||||||
private lateinit var presentationLayout: LinearLayout
|
private lateinit var presentationLayout: LinearLayout
|
||||||
|
|
||||||
private fun initializeRenderer() {
|
private fun inputStreamToCache(outputFilename: String, inputStream: InputStream): File {
|
||||||
|
val fileCached = File(cacheDir, outputFilename)
|
||||||
val output = FileOutputStream(fileCached)
|
val output = FileOutputStream(fileCached)
|
||||||
val inputStream = resources.openRawResource(testPdf)
|
|
||||||
while (inputStream.available() > 0) {
|
while (inputStream.available() > 0) {
|
||||||
inputStream.copyTo(output)
|
inputStream.copyTo(output)
|
||||||
}
|
}
|
||||||
inputStream.close()
|
inputStream.close()
|
||||||
output.close()
|
output.close()
|
||||||
val pfd = ParcelFileDescriptor.open(fileCached, ParcelFileDescriptor.MODE_READ_ONLY)
|
return fileCached
|
||||||
renderer = PdfRenderer(pfd)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderPagesToMap(map: MutableMap<Int, Bitmap>, width: Int, height: Int) {
|
private fun initializePdfDocument() {
|
||||||
map.clear()
|
val inputStream = resources.openRawResource(R.raw.testpdf)
|
||||||
val numPages = renderer.pageCount
|
pdfDocument = PdfDocument(inputStreamToCache("cached.pdf", inputStream), true)
|
||||||
for (i in 0..<numPages) {
|
|
||||||
map[i] = renderPage(i, width, height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private fun renderThumbnails() {
|
|
||||||
renderPagesToMap(bitmapThumbnails, thumbnailWidth, thumbnailHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun renderPage(index: Int, width: Int, height: Int): Bitmap {
|
|
||||||
val page = renderer.openPage(index)
|
|
||||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
|
||||||
page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
|
|
||||||
page.close()
|
|
||||||
return bitmap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyPresentation(outerContext: Context, display: Display) : Presentation(outerContext, display) {
|
class MyPresentation(outerContext: Context, display: Display) : Presentation(outerContext, display) {
|
||||||
|
@ -93,11 +75,11 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
val metrics = DisplayMetrics()
|
val metrics = DisplayMetrics()
|
||||||
presentationDisplay.getMetrics(metrics)
|
presentationDisplay.getMetrics(metrics)
|
||||||
val maxHeight = metrics.heightPixels
|
val maxHeight: Int = metrics.heightPixels
|
||||||
val maxWidth = maxHeight * 5 / 7
|
val maxWidth: Int = min(maxHeight*5/7, metrics.widthPixels)
|
||||||
renderPagesToMap(bitmapPagesPresentation, maxWidth, maxHeight)
|
pdfDocument.renderPagesPresentation(maxWidth, maxHeight)
|
||||||
presentationLayout = LinearLayout(presentation.context)
|
presentationLayout = LinearLayout(presentation.context)
|
||||||
for (bitmap in bitmapPagesPresentation.values) {
|
for (bitmap in pdfDocument.bitmapPagesPresentation.values) {
|
||||||
val img = ImageView(this)
|
val img = ImageView(this)
|
||||||
img.setImageBitmap(bitmap)
|
img.setImageBitmap(bitmap)
|
||||||
presentationLayout.addView(img)
|
presentationLayout.addView(img)
|
||||||
|
@ -138,11 +120,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||||
navView.setupWithNavController(navController)
|
navView.setupWithNavController(navController)
|
||||||
|
|
||||||
fileCached = File(cacheDir, "cached.pdf")
|
initializePdfDocument()
|
||||||
initializeRenderer()
|
pdfDocument.renderThumbnails(thumbnailWidth, thumbnailHeight)
|
||||||
renderThumbnails()
|
|
||||||
val container = findViewById<LinearLayout>(R.id.thumbnails_layout)
|
val container = findViewById<LinearLayout>(R.id.thumbnails_layout)
|
||||||
for (bitmap in bitmapThumbnails.values) {
|
for (bitmap in pdfDocument.bitmapThumbnails.values) {
|
||||||
val img = ImageView(this)
|
val img = ImageView(this)
|
||||||
img.setImageBitmap(bitmap)
|
img.setImageBitmap(bitmap)
|
||||||
container.addView(img)
|
container.addView(img)
|
||||||
|
|
|
@ -23,7 +23,7 @@ class GalleryFragment : Fragment() {
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
val galleryViewModel =
|
val galleryViewModel =
|
||||||
ViewModelProvider(this).get(GalleryViewModel::class.java)
|
ViewModelProvider(this)[GalleryViewModel::class.java]
|
||||||
|
|
||||||
_binding = FragmentGalleryBinding.inflate(inflater, container, false)
|
_binding = FragmentGalleryBinding.inflate(inflater, container, false)
|
||||||
val root: View = binding.root
|
val root: View = binding.root
|
||||||
|
|
|
@ -23,7 +23,7 @@ class HomeFragment : Fragment() {
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
val homeViewModel =
|
val homeViewModel =
|
||||||
ViewModelProvider(this).get(HomeViewModel::class.java)
|
ViewModelProvider(this)[HomeViewModel::class.java]
|
||||||
|
|
||||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||||
val root: View = binding.root
|
val root: View = binding.root
|
||||||
|
|
|
@ -23,7 +23,7 @@ class SlideshowFragment : Fragment() {
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
val slideshowViewModel =
|
val slideshowViewModel =
|
||||||
ViewModelProvider(this).get(SlideshowViewModel::class.java)
|
ViewModelProvider(this)[SlideshowViewModel::class.java]
|
||||||
|
|
||||||
_binding = FragmentSlideshowBinding.inflate(inflater, container, false)
|
_binding = FragmentSlideshowBinding.inflate(inflater, container, false)
|
||||||
val root: View = binding.root
|
val root: View = binding.root
|
||||||
|
|
Loading…
Reference in New Issue