PDFDocument and PDFPage

  • Hello all.

    I would like to do a sort-of slideshow using pages from a PDF file.
    I started with rendering a page in the following way:

    1) Loaded a PDF using PDFDocument
    2) Extracted a page with PDFPage
    3) Got the data representation
    4) Created a NSImage with it
    5) Painted the image on a custom view.

    Now the problem is how to scale the PDFPage so that the created image
    fit the size of the custom view.

    Basically I would like to mimic some of the behaviors of PDFView (zoom
    in/zoom out) but I don't want to use it because I would like to apply
    Quartz transitions between the page switches.

    Does anyone know a way to achieve this?

    Thank you.
  • On 2 Oct 2006, at 00:17, Fabio Mancinelli wrote:

    > Now the problem is how to scale the PDFPage so that the created
    > image fit the size of the custom view.

    No need to scale the PDFPage object, just use an affine transform
    when drawing to the custom view to size the image  as needed. If you
    are not familiar with transforms it's easily looked up in the
    documentation (NSAffineTransform).

    Good luck,
    António

    -----------------------------------------
    Accepting others as they are
    brings a wonderful freedom
    to your own mind.

    --The Peace Formula
    -----------------------------------------
  • On 2 Oct 2006, at 08:24, Antonio Nunes wrote:

    >> Now the problem is how to scale the PDFPage so that the created
    >> image fit the size of the custom view.
    >
    > No need to scale the PDFPage object, just use an affine transform
    > when drawing to the custom view to size the image  as needed. If
    > you are not familiar with transforms it's easily looked up in the
    > documentation (NSAffineTransform).

    Alternatively you can resize the created NSImage object with it's
    setSize method (and be sure to read up on its setScalesWhenResized
    method too).

    António

    -----------------------------------------
    Accepting others as they are
    brings a wonderful freedom
    to your own mind.

    --The Peace Formula
    -----------------------------------------
  • Antonio Nunes wrote:
    > On 2 Oct 2006, at 08:24, Antonio Nunes wrote:
    >
    >>> Now the problem is how to scale the PDFPage so that the created image
    >>> fit the size of the custom view.
    >>
    >> No need to scale the PDFPage object, just use an affine transform when
    >> drawing to the custom view to size the image  as needed. If you are
    >> not familiar with transforms it's easily looked up in the
    >> documentation (NSAffineTransform).
    >
    > Alternatively you can resize the created NSImage object with it's
    > setSize method (and be sure to read up on its setScalesWhenResized
    > method too).
    >
    > António
    >

    Thanks for your answer.
    I already do the trick of setSize + setScalesWhenResized but it doesn't
    work well. The NSImage generated from the PDFPage, when scaled down lose
    its quality, and when rescaled up becomes unreadable (because it is the
    low quality image that is rescaled)

    This made me think that the process PDFPage->NSImage->Draw is not the
    best way to do it, unless you perform the PDFPage->NSImage conversion
    every time there is a redraw (and I don't know if it is
    performance-friendly).

    Moreover, my question was raised because of the render quality. Instead
    of scaling the NSImage after the conversion from the PDFPage (images are
    pixel based), I would like to scale the PDFPage before because I guess
    that in this way I can preserve the quality of the rendering of the
    PDFPage (that is not pixel based and scales well), generating an NSImage
    already at the right size.

    Thanks again,
    Fabio
  • On 2 Oct 2006, at 09:51, Fabio Mancinelli wrote:

    > I already do the trick of setSize + setScalesWhenResized but it
    > doesn't work well. The NSImage generated from the PDFPage, when
    > scaled down lose its quality, and when rescaled up becomes
    > unreadable (because it is the low quality image that is rescaled)

    To retain the original quality of the image use its setDataRetained
    method with a value of YES before scaling it the first time, e.g.
    immediately after creating the NSImage object.

    > Moreover, my question was raised because of the render quality.
    > Instead of scaling the NSImage after the conversion from the
    > PDFPage (images are pixel based), I would like to scale the PDFPage
    > before because I guess that in this way I can preserve the quality
    > of the rendering of the PDFPage (that is not pixel based and scales
    > well), generating an NSImage already at the right size.

    I am not aware of a way to directly scale a PDFPage. You can scale
    the drawing of the page, as I wrote previously, by using an NSAffine
    transform. I suppose you could render the PDF offscreen and grab that
    representation into an image. Others may be able to provide a better
    solution to this.

    > Basically I would like to mimic some of the behaviors of PDFView
    > (zoom in/zoom out) but I don't want to use it because I would like
    > to apply Quartz transitions between the page switches.

    Is there a particular reason you can't just render the PDF directly
    to your view? The project I'm working on doesn't use PDFView either:
    it uses transforms to size and place the PDFPages in the view.

    HTH,
    António

    -----------------------------------------------------------
    And could you keep your heart in wonder
    at the daily miracles of your life,
    your pain would not seem less wondrous
    than your joy.

    --Kahlil Gibran
    -----------------------------------------------------------
  • Antonio Nunes wrote:

    > To retain the original quality of the image use its setDataRetained
    > method with a value of YES before scaling it the first time, e.g.
    > immediately after creating the NSImage object.
    >
    Thank you. It works fine with this setting.

    > I am not aware of a way to directly scale a PDFPage. You can scale the
    > drawing of the page, as I wrote previously, by using an NSAffine
    > transform. I suppose you could render the PDF offscreen and grab that
    > representation into an image. Others may be able to provide a better
    > solution to this.
    >
    Currently what I do is the following:

    PDFPage *currentPage = [PDFDocument pageAtIndex:pageNumber];
    NSData *data = [currentPage dataRepresentation];
    NSImage *image = [[NSImage alloc] initWithData:data];

    and then, in the drawRect of the view I do:

    [image setScalesWhenResized:YES];
    NSRect bounds = [self bounds];
    [image setSize:bounds.size];
    [image drawInRect:drawingRect fromRect:imageRect
                  operation:NSCompositeCopy fraction:1.0];

    I haven't found in the PDFPage class any instance method that could be
    used to draw somewhere the page. There is this drawWithBox method but it
    doesn't take any "destination".

    > Is there a particular reason you can't just render the PDF directly to
    > your view? The project I'm working on doesn't use PDFView either: it
    > uses transforms to size and place the PDFPages in the view.
    >
    I can do it.
    The problem I have is... how exactly? :)

    Thank you again for your help.
    Fabio
  • On 2 Oct 2006, at 11:48, Fabio Mancinelli wrote:

    > I haven't found in the PDFPage class any instance method that could
    > be used to draw somewhere the page. There is this drawWithBox
    > method but it doesn't take any "destination".

    Yes, that's what you need to have the page drawn. There is indeed no
    way of specifying coordinates for where to draw, hence the need to
    use an affine transform to transform the graphics context's
    transformation matrix so that the PDFPage appears at the right place
    and at the desired size. I suggest you read up on the use of
    coordinate systems and transforms.

    This is a good starting point:
    http://developer.apple.com/documentation/Cocoa/Conceptual/
    CocoaDrawingGuide/Introduction/chapter_1_section_1.html

    Particularly:
    http://developer.apple.com/documentation/Cocoa/Conceptual/
    CocoaDrawingGuide/Transforms/chapter_4_section_1.html#//apple_ref/doc/
    uid/TP40003290-CH204-BCIDJJBI

    António

    -----------------------------------------------------------
    What you have inside you expresses itself through both your
    choice of words and the level of energy you assign to them.
    The more healed, whole and connected you feel inside,
    the more healing your words will be.

    --Rita Goswami
    -----------------------------------------------------------
  • Antonio Nunes wrote:
    > On 2 Oct 2006, at 11:48, Fabio Mancinelli wrote:
    >
    >> I haven't found in the PDFPage class any instance method that could be
    >> used to draw somewhere the page. There is this drawWithBox method but
    >> it doesn't take any "destination".
    >
    > Yes, that's what you need to have the page drawn. There is indeed no way
    > of specifying coordinates for where to draw, hence the need to use an
    > affine transform to transform the graphics context's transformation
    > matrix so that the PDFPage appears at the right place and at the desired
    > size. I suggest you read up on the use of coordinate systems and
    > transforms.
    >

    Antonio thank you.
    Actually I have realized that was a misunderstanding of how things work
    that prevented me to see that it was very simple to do what I wanted to do:

    NSAffineTransform* xform = [NSAffineTransform transform];
    [xform scaleXBy:2.0 yBy:1.5];
    [xform concat];
    [currentPage drawWithBox:kPDFDisplayBoxMediaBox];

    And here it is! (Of course scaling factors are just for testing purposes :))

    Anyway there is something that I am still missing.
    concat, drawWithBox (and even, for example NSColor's set) do not take
    any explicit parameter regarding the "target" of their actions.

    I would have expected to have something like

    [destination apply:xform]
    [currentPage drawTo:destination drawWithBox:kPDFDisplayBoxMediaBox];

    but it seems that this "destination" is implicit and "automatically"
    recognized by the methods.

    This is something strange to me. And in the the documentation is not
    clearly explained.

    Thank you again.
    Fabio
  • Sorry, once again I forgot to edit the Subject Line. My Subjcet Line
    was:

    Cocoa-dev Digest, Vol 3, Issue 1203

    --
    Heinrich Giesen
    <giesenH...>
previous month october 2006 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today