سؤال

هذا ما لدي حتى الآن:

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];

يفترض الرمز أن PNG 200x200 سيكون أقل من 128 ألف ، وهو حد مقاسي. 200x200 كبير بما يكفي ، لكنني أفضل أن أفرغ الحجم إن أمكن ذلك.

ها هي مشكلتي:

  1. الرمز لا يعمل. أتحقق من حجم الملف الذي تم تصديره وهو بنفس حجم الأصلي.
  2. هل هناك طريقة للتنبؤ بحجم ملف الإخراج قبل التصدير ، حتى أتمكن من الحد من الأبعاد ولكن ما زلت أحصل على صورة أقل من 128 ألف؟

ها هو رمز العمل. إنه قذر إلى حد ما ويمكن أن يستخدم بعض التحسينات ، ولكن في هذه المرحلة ، يتم تشغيله بسرعة كافية لدرجة أنني لا أهتم. يكرر أكثر من 100x لمعظم الصور ، وينتهي بالميلي ثانية. أيضا ، يتم الإعلان عن هذه الطريقة في فئة على NSImage.

- (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;
}
هل كانت مفيدة؟

المحلول

ل 1.

كما ذكر ملصق آخر ، يغير تعيين فقط أحجام عرض الصورة ، وليس بيانات البكسل الفعلية لملف الصورة الأساسي.

لتغيير الحجم ، قد ترغب في إعادة رسم الصورة المصدر على nsimagerep ثم كتابة ذلك إلى ملف.

يحتوي منشور المدونة هذا على بعض رمز النماذج حول كيفية القيام بتغيير الحجم بهذه الطريقة.

كيفية تغيير حجم nsimage

ل 2.

لا أعتقد أنه لا يمكنك على الأقل إنشاء الكائن في الذاكرة والتحقق من طول الصورة. سوف تعتمد البايتات الفعلية المستخدمة على نوع الصورة. سيكون من السهل التنبؤ بحجم النقطات مع ArgB ، لكن PNG و JPEG سيكونون أكثر صعوبة.

نصائح أخرى

[imageData length] يجب أن يعطيك طول محتويات NSData ، والتي أفهم أنها حجم الملف النهائي عند كتابتها إلى القرص. يجب أن يمنحك ذلك فرصة لزيادة حجم الملف قبل كتابته بالفعل.

لماذا لا تتقلص الصورة أو تنمو مستندات setSize:

يحدد حجم تمثيل الصورة مع الأبعاد الفعلية لبيانات الصورة دقة الصورة.

لذلك قد يكون ذلك من خلال تحديد الحجم وعدم تغيير الدقة ، فأنت لا تقوم بتعديل أي وحدات بكسل ، فقط الطريقة التي يجب أن تفسر بها وحدات البكسل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top