Frage

Hier ist, was ich bisher habe:

NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:
               [file.image TIFFRepresentation]];
// Resize image to 200x200
CGFloat maxSize = 200.0;
NSSize imageSize = imageRep.size;
if (imageSize.height>maxSize || imageSize.width>maxSize) {
    // Find the aspect ratio
    CGFloat aspectRatio = imageSize.height/imageSize.width;
    CGSize newImageSize;
    if (aspectRatio > 1.0) {
        newImageSize = CGSizeMake(maxSize / aspectRatio, maxSize);
    } else if (aspectRatio < 1.0) {
        newImageSize = CGSizeMake(maxSize, maxSize * aspectRatio);
    } else {
        newImageSize = CGSizeMake(maxSize, maxSize);
    }
    [imageRep setSize:NSSizeFromCGSize(newImageSize)];
}


NSData *imageData = [imageRep representationUsingType:NSPNGFileType properties:nil];
NSString *outputFilePath = [@"~/Desktop/output.png" stringByExpandingTildeInPath];
[imageData writeToFile:outputFilePath atomically:NO];

Der Code geht davon aus, dass ein 200x200 PNG geringer sein wird als 128K, die meine Größenbeschränkung ist. 200x200 ist groß genug, aber ich würde zu max aus der Größe bevorzugen, wenn überhaupt möglich.

Hier sind meine zwei Probleme:

  1. Der Code funktioniert nicht. Ich überprüfen Sie die Größe der exportierten Datei und es ist die gleiche Größe wie das Original.
  2. Gibt es eine Möglichkeit, die Größe der Ausgabedatei, bevor ich den Export vorherzusagen, so kann ich max den Abmessungen, aber immer noch ein Bild erhalten, das weniger ist als 128 K?

Hier ist der Arbeitscode. Es ist ziemlich schlampig und könnte wahrscheinlich einige Optimierungen verwenden, aber an diesem Punkt läuft es schnell genug, dass ich interessiere mich nicht. Es iteriert 100x für die meisten Bilder, und es ist vorbei in Millisekunden. Auch dieses Verfahren ist in einer Kategorie auf NSImage erklärt.

- (NSData *)resizeImageWithBitSize:(NSInteger)size 
                      andImageType:(NSBitmapImageFileType)fileType {

    CGFloat maxSize = 500.0;
    NSSize originalImageSize = self.size;
    NSSize newImageSize;
    NSData *returnImageData;
    NSInteger imageIsTooBig = 1000;

    while (imageIsTooBig > 0) {
            if (originalImageSize.height>maxSize || originalImageSize.width>maxSize) {
            // Find the aspect ratio
            CGFloat aspectRatio = originalImageSize.height/originalImageSize.width;
            if (aspectRatio > 1.0) {
                newImageSize = NSMakeSize(maxSize / aspectRatio, maxSize);
            } else if (aspectRatio < 1.0) {
                newImageSize = NSMakeSize(maxSize, maxSize * aspectRatio);
            } else {
                newImageSize = NSMakeSize(maxSize, maxSize);
            }
        } else {
            newImageSize = originalImageSize;
        }

        NSImage *resizedImage = [[NSImage alloc] initWithSize:newImageSize];

        [resizedImage lockFocus];
        [self drawInRect:NSMakeRect(0, 0, newImageSize.width, newImageSize.height)
                fromRect: NSMakeRect(0, 0, originalImageSize.width, originalImageSize.height) 
               operation: NSCompositeSourceOver 
                fraction: 1.0];
        [resizedImage unlockFocus];

        NSData *tiffData = [resizedImage TIFFRepresentation];
        [resizedImage release];

        NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:tiffData];
        NSDictionary *imagePropDict = [NSDictionary 
                                       dictionaryWithObject:[NSNumber numberWithFloat:0.85] 
                                                     forKey:NSImageCompressionFactor];

        returnImageData = [imageRep representationUsingType:fileType properties:imagePropDict];
        [imageRep release];

        if ([returnImageData length] > size) {
            maxSize = maxSize * 0.99;
            imageIsTooBig--;
        } else {
            imageIsTooBig = 0;
        }

    }

    return returnImageData;
}
War es hilfreich?

Lösung

Für 1.

Als ein weiteres Plakat erwähnte setSize nur Abspaltungen Displaygrößen des Bildes und nicht die tatsächlichen Pixeldaten der zugrunde liegenden Bilddatei.

Zum Ändern der Größe, können Sie das Quellbild auf ein anderes NSImageRep neu zu zeichnen wollen, und dann, dass auf Datei schreiben.

Dieser Blog-Eintrag enthält einige Beispiel-Code, wie Sie die Größe ändern auf diese Weise zu tun.

Wie ein Ändern der Größe NSImage

2.

Ich glaube nicht, können Sie, ohne zumindest das Objekt im Speicher zu schaffen und die Länge des Bildes überprüfen. Das tatsächliche Bytes verwendet wird auf dem Bildtyp abhängig sein. Bitmaps mit ARGB wird leicht sein, ihre Größe vorherzusagen, aber PNG und JPEG würde viel schwieriger sein.

Andere Tipps

[imageData length] sollten Sie die Länge der NSData des Inhalts, die ich verstehe die endgültige Dateigröße sein, wenn auf der Platte geschrieben. Das sollte Ihnen eine Chance geben, um die Größe der Datei, bevor sie tatsächlich zu schreiben um es zu maximieren.

Wie, warum das Bild nicht schrumpft oder wächst, nach die Dokumentation für setSize :

  

Die Größe einer Bilddarstellung mit den physikalischen Dimensionen der Bilddaten kombiniert bestimmt die Auflösung des Bildes.

So es sein, dass durch die Größe einstellen und die Auflösung nicht ändern Sie keine Pixel zu modifizieren, sondern nur die Art und Weise, sollen die Pixel interpretiert werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top