Android图片转Pdf原生的示例

1、生成pdf的步骤:

  (1).建立PdfDocument
  val document = PdfDocument()
  
  (2).创建每页的具体信息,设置宽高和页数
  val pageInfo = PdfDocument.PageInfo.Builder(view.width, 
  view.height, pdfCount).create()
  
  (3). 设置每页的内容
  val page = document.startPage(pageInfo)
  val canvas: Canvas = page.canvas
  view.draw(canvas)

  (4).关闭每一页
  document.finishPage(page)

  (5).写入数据
  document.writeTo(FileOutputStream(pdfFile))

2、示例如下:

package com.zw.pdfkotlindemo

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.*
import android.graphics.pdf.PdfDocument
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import java.io.File
import java.io.FileOutputStream
import java.io.IOException

/**
 * @author : zw
 * @date : 2023/7/20
 * @email : zhang15178@163.com
 * @description :
 */
class OriginalActivity:AppCompatActivity(){

    private lateinit var llContentView: LinearLayout
    private lateinit var btnPdf: Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)

        llContentView = findViewById(R.id.ll_content_view)
        btnPdf = findViewById(R.id.btn_pdf)
        btnPdf.setOnClickListener {
            checkSelfPermission()
            pngToPdf()
        }

        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissions(
                arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE),
                1001
            )
        } else {
            Toast.makeText(this, "已申请权限", Toast.LENGTH_SHORT).show()
        }
    }


    private fun checkSelfPermission(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                val intent = Intent()
                intent.action = Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
//               intent.data = Uri.parse("package:$packageName")
                intent.data = FileProvider.getUriForFile(this,packageName+".fileprovider",
                    File("/sdcard")
                )
                startActivity(intent)
            }
        }
    }

    private fun pngToPdf() {
        val basePath = getExternalFilesDir(null)?.absolutePath
        val pdfFilePath: String = basePath + File.separator.toString() + "generate.pdf"
        val pngFilePath = Environment.getExternalStorageDirectory().absolutePath+"/picture/"

        val fullFile = File(pngFilePath)
        if (fullFile.exists()){
            Log.i("TAG", "list====${fullFile.absolutePath}")
        }
        val listFile = imageFileListReader(fullFile)
        Log.i("TAG", "list====${listFile.size}")
        generatePdf(llContentView, listFile, pdfFilePath)
    }


    private fun generatePdf(view: View, listFile: ArrayList<File>, savePdfPath: String) {
        val time = System.currentTimeMillis()
        Log.i("TAG", "PDF的文件生成,正在开始----$time")
        if (listFile.size == 0) {
            Log.i("TAG", "list为空")
            return
        }
        //总页数
        val pdfCount = listFile.size

        //1, 建立PdfDocument
        val document = PdfDocument()

        //生成多页的pdf
        for (i in 0 until pdfCount) {
            // setContentRect(new Rect(0,60,view.getWidth(),60))
            //2 crate a page description
            val pageInfo = PdfDocument.PageInfo.Builder(
                view.width, view.height, pdfCount
            ).create()

            val file = listFile[i].absolutePath
            //3、start a page
            val page = document.startPage(pageInfo)
            val canvas: Canvas = page.canvas
            var mBitmap = BitmapFactory.decodeFile(file)
            mBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true)
            //为了完整显示,进行缩放
            mBitmap = imageScale(mBitmap, view.width, view.height)
            //将布局绘制在中间位置
            canvas.drawBitmap(
                mBitmap,
                view.width / 2.0f - mBitmap.width / 2,
                view.height / 2.0f - mBitmap.height / 2,
                Paint()
            );
            view.draw(canvas)
            ///5、finish the page
            document.finishPage(page)
            mBitmap.recycle()
        }
        try {
            //write the document content
            document.writeTo(FileOutputStream(File(savePdfPath)))
            Log.i("TAG", "PDF的文件生成,已完成---${System.currentTimeMillis() - time}")
        } catch (e: IOException) {
            Log.i("TAG", "文件生成失败---${e.printStackTrace()}")

        }
        //close the document
        document.close()
    }


    fun readResourceIdGeneratePdf(view: View) {
        val basePath = getExternalFilesDir(null)?.absolutePath
        val pdfFilePath: String = basePath + File.separator.toString() + "generate.pdf"
        Log.i("TAG", "generatePdf:===$pdfFilePath")
        val pdfFile = File(pdfFilePath)
        if (pdfFile.exists()) {
            pdfFile.delete()
        }
        val pdfCount = 3 //总页数
        val document = PdfDocument() //1, 建立PdfDocument

        //生成多页的pdf
        for (i in 0 until pdfCount) {
            //  .setContentRect(new Rect(0,60,view.getWidth(),60))
            //2 crate a page description
            val pageInfo = PdfDocument.PageInfo.Builder(
                view.width, view.height, pdfCount
            ).create()
            //3、start a page
            val page = document.startPage(pageInfo)
            val canvas: Canvas = page.canvas
            var mBitmap = BitmapFactory.decodeResource(resources, R.mipmap.s1)
            if (i == 1) {
                mBitmap = BitmapFactory.decodeResource(resources, R.mipmap.s2)
            } else if (i == 2) {
                mBitmap = BitmapFactory.decodeResource(resources, R.mipmap.s3)
            }
            mBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true)
            //为了完整显示,进行缩放
            mBitmap = imageScale(mBitmap, view.width, view.height)
            //将布局绘制在中间位置
            canvas.drawBitmap(
                mBitmap,
                view.width / 2.0f - mBitmap.width / 2,
                view.height / 2.0f - mBitmap.height / 2,
                Paint()
            );
            view.draw(canvas)
            ///5、finish the page
            document.finishPage(page)
            mBitmap.recycle()
        }
        try {
            //write the document content
            document.writeTo(FileOutputStream(pdfFile))
            Log.i("TAG", "文件已生成")
        } catch (e: IOException) {
            Log.i("TAG", "文件生成失败---${e.printStackTrace()}")

        }
        //close the document
        document.close()

    }


    fun viewToPdf(view: View) {
        val basePath = getExternalFilesDir(null)?.absolutePath
        val pdfFilePath: String = basePath + File.separator.toString() + "generate.pdf"
        Log.i("TAG", "generatePdf:===$pdfFilePath")
        val pdfFile = File(pdfFilePath)
        if (pdfFile.exists()) {
            pdfFile.delete()
        }
        //总页数
        val pdfCount = 3
        //1, 建立PdfDocument
        val document = PdfDocument()

        //生成多页的pdf
        for (i in 0 until pdfCount) {
            //  .setContentRect(new Rect(0,60,view.getWidth(),60))
            //2 crate a page description
            val pageInfo = PdfDocument.PageInfo.Builder(
                view.width, view.height, pdfCount
            ).create()
            //3、start a page
            val page = document.startPage(pageInfo)
            val canvas: Canvas = page.canvas
            view.draw(canvas)
            ///5、finish the page
            document.finishPage(page)
        }
        try {
            //write the document content
            document.writeTo(FileOutputStream(pdfFile))
            Log.i("TAG", "文件已生成")
        } catch (e: IOException) {
            Log.i("TAG", "文件生成失败---${e.printStackTrace()}")

        }
        //close the document
        document.close()

    }

    /**
     * 按比例缩放图片,正方形
     *
     * @param origin 原图
     * @param ratio  比例
     * @return 新的bitmap
     */
    fun scaleBitmapWithSquare(origin: Bitmap?, ratio: Float): Bitmap? {
        if (origin == null) {
            return null
        }
        var width = origin.width
        var height = origin.height
        val matrix = Matrix()
        matrix.preScale(ratio, ratio)
        if (width > height) {
            width = height
        } else {
            height = width
        }
        val newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false)
        if (newBM.equals(origin)) {
            return newBM
        }
        origin.recycle()
        return newBM
    }

    /**
     * 根据给定的宽和高进行拉伸
     * @param bitmap
     * 源
     * @param dst_w
     * 输出宽度
     * @param dst_h
     * 输出高度
     * @return
     */
    private fun imageScale(bitmap: Bitmap, dst_w: Int, dst_h: Int): Bitmap {
        val srcW = bitmap.width
        val srcH = bitmap.height
        val scaleW = dst_w.toFloat() / srcW
        val scaleH = dst_h.toFloat() / srcH

        Log.i("---", "imageScale: ----$scaleW----$scaleH")
        val matrix = Matrix()
        if (scaleW > scaleH) {
            matrix.postScale(scaleH, scaleH)
        } else {
            matrix.postScale(scaleW, scaleW)
        }

        return Bitmap.createBitmap(
            bitmap, 0, 0, srcW, srcH, matrix,
            true
        )
    }

    private fun imageFileListReader(root: File): ArrayList<File> {
        val fileList: ArrayList<File> = ArrayList()
        val files = root.listFiles()
        if (files != null && files.isNotEmpty()) {
            for (i in files.indices)
                if (files[i].name.endsWith(".jpg") ||
                    files[i].name.endsWith(".png")
                )
                    fileList.add(files[i])
        }
        return fileList
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值