• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Image gets wrong resolution value on Snow Leopard
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Image gets wrong resolution value on Snow Leopard


  • Subject: Image gets wrong resolution value on Snow Leopard
  • From: Randall Meadows <email@hidden>
  • Date: Mon, 7 Dec 2009 17:58:03 -0700

In this application, I have a method that reads in an image and writes it back out with a different resolution.  This resolution is specified by the user via a textfield in a sheet.

On Leopard, the method works as expected; whatever value for the resolution is specified is what is actually used to write out the image.

But on Snow Leopard....sigh.  The client has asked that this textfield's value default to "250", indicating the image should be written out with a DPI of 250 pixels/inch.  When that value is used, the resulting image does NOT have a resolution of 250, but rather "72.05 x 72.03 pixels/inch" as indicated by Preview's Info window.  GraphicConverter and Photoshop agree with this.  I tried various values, including 249, 248, 245, and 239--all these resulted in the "wrong" value, but lo and behold "240" *works*.

I've posted the method at <http://paste.lisp.org/display/91743>, so you can turn on line numbers for easy reference, but I'll also paste it here for easy discussion:

- (void)exportImageDefinition:(AMImageDefinition *)imageDefinition
                  destination:(NSString *)destination
                    retouched:(BOOL)retouched
              revertRetouched:(BOOL)revertRetouch
                      cropped:(BOOL)cropped
                revertCropped:(BOOL)revertCrop
                   resolution:(float)resolution
                 recompressed:(BOOL)recompressed
                     fileType:(NSString *)fileType
                     settings:(void *)settings
              appendExtension:(BOOL)appendExtension
                    writePath:(NSString *)writePath
                stripMetadata:(BOOL)stripMetadata
{
   NSString  *imagePath = nil, *savePath = writePath;
   BOOL      isDir;

   if (retouched) {
      imagePath = [imageDefinition retouchedImagePathForSource:retouchedSource];
      if (revertRetouch && !imagePath) {
         imagePath = [imageDefinition imagePath];
      }
   }
   else {
      imagePath = ((![imageDefinition retouchedImagePathForSource:retouchedSource] || revertRetouch) ?
                   [imageDefinition imagePath] : nil);
   }

   if (!recompressed) {
      // The fileType may be wrong, because it just blindly takes whatever the menu says, without
      // checking whether it *should* be recompressed or not.
      NSString   *extension = [imagePath pathExtension];
      fileType = [self fileTypeForExtension:extension];
   }
   OSType  creator = '8BIM' /* Photoshop */, typeCode = [self typeCodeForFileType:fileType];

   if ([[NSFileManager defaultManager] fileExistsAtPath:savePath isDirectory:&isDir] && isDir) {
      savePath = [savePath stringByAppendingPathComponent:[[imagePath lastPathComponent]
                                                           stringByDeletingPathExtension]];

      if (!recompressed) {
         if ([imagePath pathExtension] != nil) {
            savePath = [savePath stringByAppendingPathExtension:[imagePath pathExtension]];
         }
      }
   }

   if (recompressed && imagePath && (!cropped || [imageDefinition regionOfInterest])) {
      CGImageSourceRef      imageSource = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:imagePath], NULL);
      NSMutableDictionary   *imageProperties = nil;
      NSImage               *image = nil;
      CGImageRef            imageRef = NULL;

      @try {
         if (CGImageSourceGetCount(imageSource) > 0) {
            imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
            CIImage *ciImage = [CIImage imageWithCGImage:imageRef];

            imageProperties = [NSMutableDictionary dictionaryWithDictionary:
               [(NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL) autorelease]];

            // clean up after our CGImage
            CGImageRelease(imageRef);
            imageRef = NULL;
            // convert image into nsImage
            if (ciImage != nil)
               image = [NSImageCreateWithCIImage(ciImage, imageProperties) autorelease];
         }
      }

      // clean up
      @finally {
         CFRelease(imageSource);
         imageSource = NULL;
      }

      // cancel the export if we can't open the image
      if (image != nil) {
         // configure the exporter
         //[exporter setSettings:settings];

         if (appendExtension) {
            NSString   *extension = [self extensionForFileType:fileType];
            if (extension != nil) {
               savePath = [savePath stringByAppendingPathExtension:extension];
            }
         }

         if (resolution == 0) {
            // This will be non-zero when cropping has been requested; if it's zero, don't actually
            // change the value, but use what the current value is.
            // Could probably just as easily use DPIWidth or TIFF:XResolution or TIFF:YResolution
            resolution = [[imageProperties valueForKey:@"DPIHeight"] floatValue];
         }

         if (cropped) {
            VIImageStyle *imageStyle = [[[VIImageStyle alloc] initWithPropertyList:
                                         [[imageDefinition propertiesForDestination:destination]
                                          objectForKey:@"Image Style"]]
                                        autorelease];
            NSAffineTransform   *translateTransform = [NSAffineTransform transform];
            NSAffineTransform   *scaleTransform = [NSAffineTransform transform];
            NSBezierPath      *framePath = [imageStyle framePath];
            NSBezierPath      *maskPath = [imageStyle maskPath];

            NSPoint   offset = NSZeroPoint;
            if (maskPath) {
               offset = NSMakePoint(-NSMinX([maskPath bounds]), -NSMinY([maskPath bounds]));
            }
            else if (framePath) {
               offset = NSMakePoint(NSMinX([framePath bounds]), NSMinY([framePath bounds]));
            }

            NSSize   croppedSize;
            if (maskPath) {
               croppedSize = [maskPath bounds].size;
            }
            else if (framePath) {
               croppedSize = [framePath bounds].size;
            }
            else {
               croppedSize = [image size];
            }
            NSImage *croppedImage = nil;

            croppedSize = NSMakeSize(croppedSize.width * (resolution / 72.0),
                                     croppedSize.height * (resolution / 72.0));

            [scaleTransform scaleBy:(resolution / 72.0)];
            [translateTransform translateXBy:offset.x yBy:offset.y];

            croppedImage = [[[NSImage alloc] initWithSize:croppedSize] autorelease];

            [croppedImage setCacheMode:NSImageCacheNever];
            [croppedImage setScalesWhenResized:NO];
            [croppedImage setDataRetained:YES];

            [croppedImage lockFocus];
            @try {
               NSGraphicsContext *context = [NSGraphicsContext currentContext];

               [context setShouldAntialias:YES];
               [context setImageInterpolation:NSImageInterpolationHigh];

               [scaleTransform concat];
               [translateTransform concat];

               if ([imageStyle regionOfInterest] && [imageDefinition regionOfInterest]) {
                  [[[imageDefinition regionOfInterest] transformToRegionOfInterest:[imageStyle regionOfInterest]]
                   concat];
               }

               [image drawAtPoint:NSZeroPoint
                         fromRect:NSMakeRect(0, 0, [image size].width, [image size].height)
                        operation:NSCompositeCopy
                         fraction:1.0];
            }

            @finally {
               [croppedImage unlockFocus];
            }
            image = croppedImage;
         }

         if (stripMetadata == YES) {
            imageProperties = [NSMutableDictionary dictionary];
         }

         // set the resolution for the exported image
         [imageProperties setValue:[NSNumber numberWithFloat:resolution]
                            forKey:(NSString *)kCGImagePropertyDPIHeight];
         [imageProperties setValue:[NSNumber numberWithFloat:resolution]
                            forKey:(NSString *)kCGImagePropertyDPIWidth];
         [imageProperties setValue:[NSNumber numberWithFloat:1.0]
                            forKey:(NSString *)kCGImageDestinationLossyCompressionQuality];
         [imageProperties setValue:[NSNumber numberWithLong:creator] forKey:NSFileHFSCreatorCode];
         [imageProperties setValue:[NSNumber numberWithLong:typeCode] forKey:NSFileHFSTypeCode];
         [imageProperties setValue:[NSNumber numberWithFloat:resolution] forKeyPath:@"{TIFF}.XResolution"];
         [imageProperties setValue:[NSNumber numberWithFloat:resolution] forKeyPath:@"{TIFF}.YResolution"];

         NSError   *error = nil;
         [[NSFileManager defaultManager] removeItemAtPath:savePath error:&error];
         // export the image
         if (!NSImageWriteToURL([NSURL fileURLWithPath:savePath], image, (CFStringRef)fileType, imageProperties)) {
            NSLog(@"Couldn't export image to %@", savePath);
         }
         else if (batchEditing) {
            [batchEditMonitor monitorFile:savePath
                          imageDefinition:imageDefinition
                             importSource:autoImportSource];
         }
      }
   }
   else if (!recompressed && imagePath) {
      [[NSFileManager defaultManager] removeItemAtPath:savePath error:nil];
      [[NSFileManager defaultManager] copyPath:imagePath toPath:savePath handler:nil];
      if (batchEditing) {
         [batchEditMonitor monitorFile:savePath
                       imageDefinition:imageDefinition
                          importSource:autoImportSource];
      }
   }
}


Any and all tips, suggestions, comments, etc. are greatly appreciated.
Thanks!
randy_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Prev by Date: Tracking Multiple Touches For Appropriate Label
  • Next by Date: NSScroller position
  • Previous by thread: Re: Tracking Multiple Touches For Appropriate Label
  • Next by thread: NSScroller position
  • Index(es):
    • Date
    • Thread