Создание PDF с изображениями, извлеченными из другого PDF, с использованием PDFBox слишком медленно, а созданный размер PDF намного больше, чем у исходного PDF - PullRequest
0 голосов
/ 05 мая 2019

Я разрабатываю приложение, которое берет PDF, а затем разбирает все свои изображения и сохраняет их как ArrayList растровых изображений. Эти растровые изображения могут быть затем отредактированы и затем сохранены в формате PDF Когда я пытаюсь сохранить их как PDF после редактирования или просто без редактирования, размер PDF становится в десять раз больше исходного размера PDF, и хотя я выполняю обработку каждой страницы в отдельном потоке, он все еще работает очень медленно.

например: Если я возьму PDF размером 28 МБ, потребуется около 4 минут, чтобы превратить его в PDF. В PDF имеется 20 изображений, а размер выходного PDF превышает 200 МБ.

Я использую библиотеку PDFBox от Tom Roush для Android. Tom Roush PDFBox Repo .

Это метод createPdf ():

public void createPdf() {
        document = new PDDocument();

            for(Bitmap image : images)
            {
                PDFPages page=new PDFPages();
                page.execute(image);
            }

    }

Класс asynctask PDFPages выглядит следующим образом:

public class PDFPages extends AsyncTask<Bitmap,Integer,Void>
    {

        @Override
        protected Void doInBackground(Bitmap... voids) {

            try {
                Bitmap image=voids[0];
                PDPage page = new PDPage();
                document.addPage(page);
                // Define a content stream for adding to the PDF
                PDPageContentStream contentStream = new PDPageContentStream(document, page);

                PDImageXObject ximage = LosslessFactory.createFromImage(document, image);

                // Defining and calculating position and scaling variables
                float w = image.getWidth();
                float h = image.getHeight();

                float x_pos = page.getCropBox().getWidth();
                float y_pos = page.getCropBox().getHeight();


                if (w > h) {
                    h = h * (x_pos / w);
                    w = x_pos;
                } else {
                    w = w * (y_pos / h);
                    h = y_pos;
                }

                float x_adjusted = (x_pos - w) / 2;
                float y_adjusted = (y_pos - h) / 2;

                contentStream.drawImage(ximage, x_adjusted, y_adjusted, w, h);

                // Make sure that the content stream is closed:
                contentStream.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            countPages = countPages + 1;

            if(countPages == images.size()) {
                try {
                    // Save the final pdf document to a file
                    final String path = myDir.getAbsolutePath() + "/Created.pdf";

                    document.save(path);
                    document.close();

                    Toast.makeText(process.this, "PDF successfully written to :" + path, Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                progressBar.setVisibility(View.INVISIBLE);
                saving.setVisibility(View.INVISIBLE);
                anim.cancel();

            }

        }
    }

Метод извлечения изображений из PDF следующий:


public void createImages()
    {
        try {
            //Loading the pdf file
            PDDocument document = PDDocument.load(file);
            //Getting all the pages in list
            PDPageTree pages= document.getDocumentCatalog().getPages();
            Iterator iter = pages.iterator();

            myDir = new File(root.getAbsolutePath(), "PDF/" + pdfName);
            if (!myDir.exists()) {
                myDir.mkdirs();
            }

            // i used for counting number of images
            i=0;

            while(iter.hasNext())
            {
                PDPage page=(PDPage) iter.next();
                PDResources resources=page.getResources();

                //Tom Roush code that he commented against my issue of not having resources.getImages() method
                for (COSName name : resources.getXObjectNames())
                {
                    PDXObject xobj = resources.getXObject(name);
                    if (xobj instanceof PDImageXObject)
                    {
                        bit = ((PDImageXObject)xobj).getImage();
                        //Image acquired.
                        if(bit != null) {
                            images.add(bit);
                        }
                        i=i+1;
                    }
                }
            }
            if(i == 0)
            {
                Intent intent=new Intent(process.this,MainActivity.class);
                intent.putExtra("images",i);
                startActivity(intent);
            }
            document.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        Log.i("helll","Completed CreateImages()");
    }

images - это массив массивов растровых изображений.

Входной PDF - это PDF, созданный Cam Scanner ( приложение ) с использованием 20 изображений, снятых камерой устройства. Он имеет размер 27,45 МБ, а выходной PDF имеет размер 264,10 МБ

Я скоро выложу PDF-файлы. Причина, по которой я не могу загрузить файл: в настоящее время я не на своем рабочем месте, и я полностью зависим от интернета моего телефона, и да, я живу в стране третьего мира. Поэтому я буду загружать PDF-файлы на свой диск Google и редактировать ссылки, как только получу приличное подключение к Интернету.

Мне нужен какой-то метод, с помощью которого я могу уменьшить время вывода и размер выводимого PDF.

...