Pdf.js: Add way to trim white spaces at beginning/end of documents

Created on 20 Oct 2012  路  9Comments  路  Source: mozilla/pdf.js

When viewing PDFs, there is a long area at the beginning/end of documents that is usually white and that needs to be scrolled over to get to the next page. This is very annoying when reading equations and they wrap to the next page.

If would be cool to implement something like "hide this portion of the page on the top/bottom".

I'm wondering what's the best place to add this functionality in the UI. Should there be a new button in the toolbar for "advanced" stuff like this, or how about adding an entry to the context menu?

Would a PR implementing this feature get accepted into the main repo?

1-viewer 2-feature

Most helpful comment

In case it's helpful to anyone else, I'm doing this by hand by reading pixel values directly from canvas:

  function isSingleColor(imageData) {
    let stride = 4
    for (let offset = 0; offset < stride; offset++) {
      let first = imageData[offset]
      for (let i = offset; i < imageData.length; i+=stride) {
        if (first !== imageData[i]) {
          return false
        }
      }
    }
    return true
  }

  let pageViewport = // ...
  let page = // ...
  let width = pageViewport.width
  let height = pageViewport.height

  let context = DOM.context2d(width, height);
  context.canvas.width = width
  context.canvas.height = height
  await page.render({canvasContext: context, viewport: pageViewport})

  let top = 0
  let bottom = height
  let left = 0
  let right = width
  while (top < bottom) {
    let data = context.getImageData(left, top, right - left, 1).data
    if (!isSingleColor(data)) { break; }
    top++
  }
  while (top < bottom) {
    let data = context.getImageData(left, bottom, right - left, 1).data
    if (!isSingleColor(data)) { break; }
    bottom--
  }
  while (left < right) {
    let data = context.getImageData(left, top, 1, bottom - top).data
    if (!isSingleColor(data)) { break; }
    left++
  }
  while (left < right) {
    let data = context.getImageData(right, top, 1, bottom - top).data
    if (!isSingleColor(data)) { break; }
    right--
  }

All 9 comments

MS Word 2007/2010 implements this by making the space between pages clickable and with a special cursor image. Double-clicking on it "collapses" the pages so that they start when the content starts and end when the content ends, also reducing the inter-page spacing.

This way it doesn't require neither a button nor a context menu entry, although it may be easier to turn it on/off with one.

EDIT: Actually word's feature only removes the margins, not the whitespace

EDIT: Actually word's feature only removes the margins, not the whitespace

it's not only about removing margins and whitespaces. Most pages have the page number at the bottom/top, which is not interesting for me in most cases. I would love to get rid of this as well when in "continuous mode".

Thinking of "continuous mode", maybe this could be an entry beside the other "zoom" options?

Let's close this issue unless somebody wants to implemented it and assigned.

Let's close this issue unless somebody wants to implemented it and assigned.

I'm waiting on UI/UX feedback on this one (see my first comment). I might carry the implementation, but I cannot promise anything right now.

Okular, KDE's default pdf viewer, has 'trim margin' option. It hides left/right as well as top/bottom margin. +1 for also left/right margin.

before/after screenshot.

http://imgur.com/a/7bj4M

This feature would be nice. I use the EBookDroid application for Android devices and it has this feature. There is a "crop pages (Auto)" option. Below in the picture, on the left there is a ebook without cropping and on the right the same ebook with cropping.
screenshot_2016-06-13-08-04-42-collage

Okular has two options:

  • Trim View > Trim Margins
  • Trim View > Trim To Selection

The first automatically detects the margins per page, and trims margins on every page (even if the result is that the pages have a different size). When the fit-to-width zoom option is used, each individual page has the same displayed width (thus different zoom levels per page).

The second has no autodetection, but offers maximal freedom, e.g. removing page numbers and footers/headers if wanted. I think that I'm going to try and implement this feature, since it is more powerful, likely easier to implement than auto-detecting the margins, and suitable for the most common case (a report with some title page and then many pages with the same geometry).

Edit: This is where the "Trim To Selection" feature was introduced in Okular: https://bugs.kde.org/show_bug.cgi?id=351156

Edit2: The default PDF Viewer on OS X (Preview) allows margins to be trimmed as follows: create rectangular selection, select one or more pages via the thumbnail view, select "crop" via a menu item to trim margins. To undo the trimming, one has the ability to "undo" the crop in the "undo history" (I don't see an option to remove the crop without the undo history though).
This is described in more detail at http://www.macworld.com/article/1139223/previewcrop.html.

In case it's helpful to anyone else, I'm doing this by hand by reading pixel values directly from canvas:

  function isSingleColor(imageData) {
    let stride = 4
    for (let offset = 0; offset < stride; offset++) {
      let first = imageData[offset]
      for (let i = offset; i < imageData.length; i+=stride) {
        if (first !== imageData[i]) {
          return false
        }
      }
    }
    return true
  }

  let pageViewport = // ...
  let page = // ...
  let width = pageViewport.width
  let height = pageViewport.height

  let context = DOM.context2d(width, height);
  context.canvas.width = width
  context.canvas.height = height
  await page.render({canvasContext: context, viewport: pageViewport})

  let top = 0
  let bottom = height
  let left = 0
  let right = width
  while (top < bottom) {
    let data = context.getImageData(left, top, right - left, 1).data
    if (!isSingleColor(data)) { break; }
    top++
  }
  while (top < bottom) {
    let data = context.getImageData(left, bottom, right - left, 1).data
    if (!isSingleColor(data)) { break; }
    bottom--
  }
  while (left < right) {
    let data = context.getImageData(left, top, 1, bottom - top).data
    if (!isSingleColor(data)) { break; }
    left++
  }
  while (left < right) {
    let data = context.getImageData(right, top, 1, bottom - top).data
    if (!isSingleColor(data)) { break; }
    right--
  }

Perhaps someone would be interested in posting a bounty on this?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kleins05 picture kleins05  路  3Comments

sujit-baniya picture sujit-baniya  路  3Comments

THausherr picture THausherr  路  3Comments

timvandermeij picture timvandermeij  路  4Comments

anggikolo11 picture anggikolo11  路  3Comments