Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expo - reduce PDF filesize on iOS devices

I'm currently creating an A4 PDF within my Expo-App, using the "expo-print" API (printtofileasync). The PDF includes images (photos taken from the device) and some text. I've set the PDF size to 595 width, 842 height (A4 dimensions). Unfortunately the size of the PDF is too large for my requirements (1,9MB with only 1 image).

I was able to reduce the PDF size on Android by decreasing the image size, but that does not work on iOS. I have the suspicion that on iOS Expo is simply "making screenshots" of the page, therefore changing the image size has no effect. I've already tried to decrease the whole PDF size to A5, but that's not a solution, because the PDFs needs to be printed afterwards on A4.

Any help would be appreciated!

Update: currently this my code:

const { uri, base64 } = await Print.printToFileAsync({
    width: 595,
    height: 842,
    html: 'data...',
    base64: true,
});

Share.share({
    url: 'data:application/pdf;base64,' + base64,
});
like image 508
benedikt Avatar asked Nov 06 '19 13:11

benedikt


People also ask

How do I reduce PDF file size on iPad?

Compress PDFs online with your iPad.Open Safari or any other browser, then navigate to the Acrobat online PDF compressor. Tap on Select a File and locate your PDF on your iPad. Download your compressed PDF file. You can also check how much the compressor was able to shave off the file size.

How do I reduce the MB size of a PDF?

Reduce PDF file sizes onlineThe Adobe Acrobat Compress PDF online tool lets you compress PDF files right from your browser. Use our PDF compressor to make large files smaller and easier to share.

How do I reduce PDF size to 70 %?

Go to the Compress PDF tool. Drag and drop your PDF into the toolbox to reduce the file size. Choose the compression type and click “Compress.” The PDF compression tool will shrink the file down.


Video Answer


1 Answers

I have the same problem, I change my pdf creator because html creates variable size pdf and it depends on the resolution device, I use pdf-lib it works in javascript, you can create or modify pdf, I write small example in Expo , I plan to create a library to do Additional, you can fill PDF NOTE: it similar to react-native-pdf-lib but working in only enviroment javascript

My App.tsx example:

import React from "react";
import { StyleSheet, View, Text, Button } from "react-native";
import { Asset } from "expo-asset";
import * as Print from "expo-print";
import { degrees, PDFDocument, rgb, StandardFonts } from "pdf-lib";

export default function App({ context }: any) {
  return (
    <View style={styles.container}>
      <Button
        title="Generate PDF"
        onPress={async () => {
          const req = new XMLHttpRequest();
          /* const templateUri = Asset.fromModule(
            require("./assets/template.pdf")
          );
          console.log(templateUri); */
          const url =  'https://pdf-lib.js.org/assets/with_update_sections.pdf' // templateUri.uri
          req.open("GET", url, true);
          req.responseType = "blob";
          /*   req.onprogress = e => (t.progress = e.loaded); */
          req.onload = () => {
            const blob = req.response;
            var reader = new FileReader();
            reader.readAsDataURL(blob);
            reader.onloadend = async function() {
              const base64data = reader.result as string; // template pdf in base64
              const pdfDoc = await PDFDocument.load(base64data);
              const helveticaFont = await pdfDoc.embedFont(
                StandardFonts.Helvetica
              );

              const pages = pdfDoc.getPages();
              const firstPage = pages[0];
              const { width, height } = firstPage.getSize();
              console.log(width, height);
              firstPage.drawText('This text was added with JavaScript!', {
                x: 5,
                y: height / 2 + 300,
                size: 50,
                font: helveticaFont,
                color: rgb(0.95, 0.1, 0.1),
                rotate: degrees(-45),
              });

              const pdfDataUri = await pdfDoc.saveAsBase64({ dataUri: true });
              Print.printAsync({ uri: pdfDataUri });
            };
          };
          req.onerror = console.error;
          req.send();
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center"
  }
});
like image 98
Mike Vargas Avatar answered Oct 05 '22 11:10

Mike Vargas