Creating a file containing both an image and text

  • I would like to save screenshots from my program (as an image), with additional text data underneath, in the same file.
    Using the OS-X 'screencapture' utility I can either create a PNG or PDF file, or send one of these to the clipboard.
    I found several classes to import data from the clipboard (NSPasteBoard), and the NSAttributedString class which can write an RTFD file. That would be OK for this purpose. However, currently I can't get it to work.

    Question: how can I store an image and some text in one file in the most convenient (simple) way? Which file format should it be, PDF or RTFD, or something else?

    The following code extracts the (pdf) data from the pasteboard, and then attempts to create an RTFD file wrapper out of it.

    NSPasteboard *pb = [NSPasteboard generalPasteboard];NSArray *supportedTypes = [NSArray arrayWithObject: NSPDFPboardType];NSString *bestType = [pb availableTypeFromArray:supportedTypes];
    if (bestType != nil){  NSData * RTFDData = [pb dataForType: NSPDFPboardType];  NSError * error;  NSDictionary * dict;
      NSMutableAttributedString * myString = [[NSMutableAttributedString  alloc] initWithData: RTFDData  options:nil documentAttributes:&dict error:&error];  NSFileWrapper * fileWrapper = [myString RTFDFileWrapperFromRange:      NSMakeRange(0, [myString length]) documentAttributes: dict];  [fileWrapper writeToFile: [NSString stringWithFormat:      @"%@/screenshot.rtfd", myCurrentDirectoryPath] atomically: YES      updateFilenames: YES];
    }
    NSMutableAttributedString's initWithData call gives 'plain text' back in the documentAttributes dict, meaning it didn't recognize the PDF type. The rest does not produce a sensible RTFD file.


    Thanks for your time,

    Arthur C.
  • On 12 Jan 08, at 13:50, Arthur C. wrote:
    > I would like to save screenshots from my program (as an image), with
    > additional text data underneath, in the same file.
    > Using the OS-X 'screencapture' utility I can either create a PNG or
    > PDF file, or send one of these to the clipboard.
    > I found several classes to import data from the clipboard
    > (NSPasteBoard), and the NSAttributedString class which can write an
    > RTFD file. That would be OK for this purpose. However, currently I
    > can't get it to work.
    >
    > Question: how can I store an image and some text in one file in the
    > most convenient (simple) way? Which file format should it be, PDF or
    > RTFD, or something else?
    >
    > The following code extracts the (pdf) data from the pasteboard, and
    > then attempts to create an RTFD file wrapper out of it.
    >
    > NSPasteboard *pb = [NSPasteboard generalPasteboard];
    > NSArray *supportedTypes = [NSArray arrayWithObject: NSPDFPboardType];
    > NSString *bestType = [pb availableTypeFromArray:supportedTypes];
    > if (bestType != nil){
    > NSData * RTFDData = [pb dataForType: NSPDFPboardType];
    > NSError * error;
    > NSDictionary * dict;
    > NSMutableAttributedString * myString = [[NSMutableAttributedString
    > alloc] initWithData: RTFDData options:nil documentAttributes:&dict
    > error:&error];
    > NSFileWrapper * fileWrapper = [myString
    > RTFDFileWrapperFromRange:NSMakeRange(0, [myString length])
    > documentAttributes: dict];
    > [fileWrapper writeToFile: [NSString stringWithFormat:@"%@/
    > screenshot.rtfd", myCurrentDirectoryPath] atomically: YES
    > updateFilenames: YES];
    > }
    >
    > NSMutableAttributedString's initWithData call gives 'plain text'
    > back in the documentAttributes dict, meaning it didn't recognize the
    > PDF type. The rest does not produce a sensible RTFD file.

    What you're doing in this code doesn't make sense. You can't turn a
    PDF into an RTFD just by throwing the raw PDF data at
    [NSMutableAttributedString initWithData:] and shouting
    "Catch!" (metaphorically). I haven't used the text system enough to be
    exactly sure of the details, but I believe you'll have to create a
    text attachment for the image to go into.

    Also, I'm not sure why you're using the screencapture utility here.
    You can ask a window's contentView to render itself to an image, which
    is a lot "friendlier" than overwriting the user's pasteboard with your
    screenshot. Alternatively, if you're on 10.5, there are some new APIs
    (CGWindowListCreateImage) that'll let you capture a window directly to
    an image.
  • > You can ask a window's contentView to render itself to an image, which
    > is a lot "friendlier" than overwriting the user's pasteboard with your
    > screenshot.

    Thanks for pointing this out.
    Indeed we can get a PDF (or EPS) containing the image using
      NSData * data = [[myWindow contentView] dataWithPDFInsideRect: myRect];
    which is cleaner than using the pasteboard.

    But the question remains: how can I add text (from an NSString) to this PDF?
    Or alternatively, like in my first attempt, how to include the PDF image into an RTFD file.

    > I haven't used the text system enough to be
    > exactly sure of the details, but I believe you'll have to create a
    > text attachment for the image to go into.

    Indeed, for the latter case I found a piece of code (in "Cocoa programming", Anguish, Buck, Yacktman) that uses a text attachment to read an image (tiff) file:

    NSTextAttachment * att = [[[NSTextAttachment alloc] initWithFileWrapper: wrapper] autorelease];
    NSAttributedString * attStr = [NSAttributedString attributedStringWithAttachment: att];

    but I still don't know how to create such an attachment for PDF data in memory.

    Any further suggestions?

    Thanks for your help,

    Arthur C.
  • > But the question remains: how can I add text (from an NSString) to this PDF? > Or alternatively, like in my first attempt, how to include the PDF image into an RTFD file.
    A working solution (although not the most elegant) is to create a simple RTFD file using TextEdit, containing a PDF image and some text.
    Then, paste the RTF header in our Cocoa program, and substitute our own PDF image from
      [NSWindow dataWithPDFInsideRect: myRect]
    and our own text...
    Saving that to a folder named '.../myRTFD.rtfd' including the pdf file and 'TXT.rtf' does the job.


    Best regards,

    Arthur C.
  • Arthur C. <arthur_cw...> wrote:

    > Or alternatively, like in my first attempt, how to include the PDF image
    > into an RTFD file.
    >
    >> I haven't used the text system enough to be
    >> exactly sure of the details, but I believe you'll have to create a
    >> text attachment for the image to go into.
    >
    > Indeed, for the latter case I found a piece of code (in "Cocoa
    > programming", Anguish, Buck, Yacktman) that uses a text attachment to read
    > an image (tiff) file:
    >
    > NSTextAttachment * att
    > = [[[NSTextAttachment alloc] initWithFileWrapper: wrapper] autorelease];
    > NSAttributedString * attStr
    > = [NSAttributedString attributedStringWithAttachment: att];
    >
    > but I still don't know how to create such an attachment for PDF data in
    > memory.

    Just create the NSFileWrapper yourself.  You don't need an actual,
    existing file for it.

    Something like this:

      NSData *data = < NSData containing your PDF >;
      NSFileWrapper *wrapper
        = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease];
      [wrapper setPreferredFilename:@"SomeAppropriateName.pdf"];
      ... continue with your code ...

    --
    Stefan Haller
    Ableton
    http://www.ableton.com/
previous month january 2008 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