andytango/mupdf-js

drawPageAsPNG generates base64 with newline character

lnfel opened this issue · 2 comments

lnfel commented

Describe the bug
Generating a PNG image using drawPageAsPNG has newline after data:image/png;base64,

To Reproduce

import { createMuPdf } from "mupdf-js"

let preview = []

// Initialize mupdf and call mupdfGeneratePNG
async function mupdfPreview(file) {
  const mupdf = await createMuPdf()
  const fileArrayBuffer = await file.arrayBuffer()
  const fileBuffer = new Uint8Array(fileArrayBuffer)
  const pdf = mupdf.load(fileBuffer)
  const pages = mupdf.countPages(pdf)
  return await mupdfGeneratePNG(mupdf, pdf, file, pages)
}

// Generate previews for pdf pages and return array of base64 PNGs
async function mupdfGeneratePNG(mupdf, pdf, file, pages) {
  return new Promise((resolve, reject) => {
    try {
      for (let i = 1; i < pages; i++) {
        const base64Image = mupdf.drawPageAsPNG(pdf, i, 10) // issue is here
        preview.push(image)
      }
      
      resolve(preview)
    } catch (error) {
      console.log(error)
      reject(error)
    }
  })
}

// Handle file input on change event
async function onChange(event) {
  const files = event.target.files
  Array.from(files).forEach(async (file) => {
      if (file.type === 'application/pdf') {
        await mupdfPreview(file)
      }
  })
}

// Listen for input file change
const input = document.querySelector('[type="file"]')
input.addEventListener('change', onChange)

Expected behavior
drawPageAsPNG should return a single line base64 string like:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...

Actual behavior
base64 string has newline after data:image/png;base64,

data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAA...

# in some environments the newline would be escaped and become `%0A`, resulting to:
data:image/png;base64,%0AiVBORw0KGgoAAAANSUhEUgAA...

Log output
Paste outputs from your terminal or browser logs to help explain your problem.

Screenshots
Screen Shot 2023-03-23 at 2 29 43 PM

Desktop (please complete the following information):

  • OS: Linux and MacOS
  • OS Version: Ubuntu 22.04 LTS (GNU/Linux 5.15.0-1031-aws x86_64) and MacOS Catalina version 10.15.7
  • Browser (or Node) Chrome and Node
  • Browser (or Node) version: Chrome Version 110.0.5481.177 (Official Build) (x86_64) and Node v18.14.2
  • Architecture: x86_64

Smartphone (please complete the following information):
Not applicable

Additional context
Nothing

lnfel commented

Workaround

Replace newline with empty string.

base64Image.replace(/\n/, "")

// Edit: I realized `drawPageAsPNG` also add the new line at certain points within the base64 string,
// replacing all of those by using replaceAll
base64Image.replaceAll(/\n/g, "")

I made PR #58 which could fix this problem (there was bug with null byte at the end, but in some cases it could be converted to new line when marshalling from wasm to js)