Привет, разработчики!
Я ищу решение для сжатия PDF-файлов, PDF-файлов, которые не содержат изображений (простые плоские PDF-файлы, которые будут иметь в нем только текст).
Я использую приведенный ниже фрагмент кода для сжатия PDF-файлов, но это для PDF-файлов, содержащих изображения. но если PDF-файл не содержит изображений, он не сжимает его, иногда сжимает только до размера от 100 до 200 КБ. Код
(context as AppCompatActivity).lifecycleScope.launch(Dispatchers.IO) {
try {
val reader = PdfReader(inputPath, password.toByteArray())
//pdfOptimize(reader)
compressReader(reader)
saveReader(reader)
reader.close()
onPDFCompletion(outputPath)
} catch (e: IOException) {
Log.d("PDFCompressionActivityTEST", "execute: ${e.message}")
onPDFFailed(e.message)
} catch (e: DocumentException) {
onPDFFailed(e.message)
} catch (e: Exception) {
onPDFFailed(e.message)
}
}
@Throws(IOException::class)
private fun compressReader(reader: PdfReader) {
val n = reader.xrefSize
var `object`: PdfObject?
var stream: PRStream
for (i in 0 until n) {
`object` = reader.getPdfObject(i)
if (`object` == null || !`object`.isStream) continue
stream = `object` as PRStream
compressStream(stream)
}
reader.removeUnusedObjects()
}
@Throws(IOException::class)
private fun compressStream(stream: PRStream) {
val pdfSubType = stream[PdfName.SUBTYPE]
println(stream.type())
if (pdfSubType != null && pdfSubType.toString() == PdfName.IMAGE.toString()) {
val image = PdfImageObject(stream)
val imageBytes = image.imageAsBytes
val bmp: Bitmap =
BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) ?: return
val width = bmp.width
val height = bmp.height
val outBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val outCanvas = Canvas(outBitmap)
outCanvas.drawBitmap(bmp, 0f, 0f, null)
val imgBytes = ByteArrayOutputStream()
outBitmap.compress(Bitmap.CompressFormat.JPEG, quality, imgBytes)
stream.clear()
stream.setData(imgBytes.toByteArray(), false, PRStream.BEST_COMPRESSION)
stream.put(PdfName.TYPE, PdfName.XOBJECT)
stream.put(PdfName.SUBTYPE, PdfName.IMAGE)
stream.put(PdfName.FILTER, PdfName.DCTDECODE)
stream.put(PdfName.WIDTH, PdfNumber(width))
stream.put(PdfName.HEIGHT, PdfNumber(height))
stream.put(PdfName.BITSPERCOMPONENT, PdfNumber(8))
stream.put(PdfName.COLORSPACE, PdfName.DEVICERGB)
}
}
@Throws(DocumentException::class, IOException::class)
private fun saveReader(reader: PdfReader) {
val stamper = PdfStamper(reader, FileOutputStream(outputPath))
stamper.setFullCompression()
stamper.close()
}
Любая помощь будет оценена по достоинству. Я пытаюсь с 1 недели, но не получил никакого решения. Я видел несколько приложений в Play Store, все они могут сжимать PDF-файлы (которые не содержат изображений). Но моя логика не способна этого сделать. Пожалуйста, помогите мне.
Спасибо...
[b]Привет, разработчики[/b]! Я ищу решение для сжатия PDF-файлов, PDF-файлов, которые не содержат изображений (простые плоские PDF-файлы, которые будут иметь в нем только текст). Я использую приведенный ниже фрагмент кода для сжатия PDF-файлов, но это для PDF-файлов, содержащих изображения. но если PDF-файл не содержит изображений, он не сжимает его, иногда сжимает только до размера от 100 до 200 КБ. [b]Код[/b] [code] (context as AppCompatActivity).lifecycleScope.launch(Dispatchers.IO) { try { val reader = PdfReader(inputPath, password.toByteArray()) //pdfOptimize(reader) compressReader(reader) saveReader(reader) reader.close()
@Throws(IOException::class) private fun compressReader(reader: PdfReader) { val n = reader.xrefSize var `object`: PdfObject? var stream: PRStream for (i in 0 until n) { `object` = reader.getPdfObject(i) if (`object` == null || !`object`.isStream) continue stream = `object` as PRStream compressStream(stream) } reader.removeUnusedObjects() }
@Throws(IOException::class) private fun compressStream(stream: PRStream) { val pdfSubType = stream[PdfName.SUBTYPE] println(stream.type()) if (pdfSubType != null && pdfSubType.toString() == PdfName.IMAGE.toString()) { val image = PdfImageObject(stream) val imageBytes = image.imageAsBytes val bmp: Bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) ?: return val width = bmp.width val height = bmp.height val outBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val outCanvas = Canvas(outBitmap) outCanvas.drawBitmap(bmp, 0f, 0f, null) val imgBytes = ByteArrayOutputStream() outBitmap.compress(Bitmap.CompressFormat.JPEG, quality, imgBytes) stream.clear() stream.setData(imgBytes.toByteArray(), false, PRStream.BEST_COMPRESSION) stream.put(PdfName.TYPE, PdfName.XOBJECT) stream.put(PdfName.SUBTYPE, PdfName.IMAGE) stream.put(PdfName.FILTER, PdfName.DCTDECODE) stream.put(PdfName.WIDTH, PdfNumber(width)) stream.put(PdfName.HEIGHT, PdfNumber(height)) stream.put(PdfName.BITSPERCOMPONENT, PdfNumber(8)) stream.put(PdfName.COLORSPACE, PdfName.DEVICERGB) } }
@Throws(DocumentException::class, IOException::class) private fun saveReader(reader: PdfReader) { val stamper = PdfStamper(reader, FileOutputStream(outputPath)) stamper.setFullCompression() stamper.close() } [/code] Любая помощь будет оценена по достоинству. Я пытаюсь с 1 недели, но не получил никакого решения. Я видел несколько приложений в Play Store, все они могут сжимать PDF-файлы (которые не содержат изображений). Но моя логика не способна этого сделать. Пожалуйста, помогите мне. Спасибо...