2011-09-02 3 views

risposta

15

ho usato Mats risposta a costruire un semplice categoria sul NSData che mi dice se il suo contenuto è JPEG o PNG in base ai suoi primi 4 byte:

@interface NSData (yourCategory) 

- (BOOL)isJPG; 
- (BOOL)isPNG; 

@end 

@implementation NSData (yourCategory) 
- (BOOL)isJPG 
{ 
    if (self.length > 4) 
    { 
     unsigned char buffer[4]; 
     [self getBytes:&buffer length:4]; 

     return buffer[0]==0xff && 
       buffer[1]==0xd8 && 
       buffer[2]==0xff && 
       buffer[3]==0xe0; 
    } 

    return NO; 
} 

- (BOOL)isPNG 
{ 
    if (self.length > 4) 
    { 
     unsigned char buffer[4]; 
     [self getBytes:&buffer length:4]; 

     return buffer[0]==0x89 && 
       buffer[1]==0x50 && 
       buffer[2]==0x4e && 
       buffer[3]==0x47; 
    } 

    return NO; 
} 

@end 

E poi, è sufficiente fare un:

CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData((CFDataRef) imgData); 
CGImageRef imgRef = nil; 

if ([imgData isJPG]) 
    imgRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault); 
else if ([imgData isPNG]) 
    imgRef = CGImageCreateWithPNGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault); 

UIImage* image = [UIImage imageWithCGImage:imgRef]; 

CGImageRelease(imgRef); 
CGDataProviderRelease(imgDataProvider); 
+2

Proprio come aggiungere che non tutti i file JPEG hanno il quarto byte come e0. Risulta che ci sono più "sottotipi" realizzati da varie aziende. Vedi http://www.garykessler.net/library/file_sigs.html per almeno un elenco parziale di loro. Sulla base di ciò che ho visto finora, sembra che abbiano costantemente i primi tre byte come sopra citati, e nessun altro tipo di file sembra utilizzare gli stessi tre byte, ma non so se questo è scritto nella pietra ovunque . –

1

Ecco una versione Swift della risposta di @ apouche:

extension NSData { 
    func firstBytes(length: Int) -> [UInt8] { 
    var bytes: [UInt8] = [UInt8](count: length, repeatedValue: 0) 
    self.getBytes(&bytes, length: length) 
    return bytes 
    } 

    var isJPEG: Bool { 
    let signature:[UInt8] = [0xff, 0xd8, 0xff, 0xe0] 
    return firstBytes(4) == signature 
    } 

    var isPNG: Bool { 
    let signature:[UInt8] = [0x89, 0x50, 0x4e, 0x47] 
    return firstBytes(4) == signature 
    } 
} 
0

È possibile creare CGImageSourceRef e poi chiedere per il tipo di immagine

CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL); 

    if(imageSource) 
    { 
     // this is the type of image (e.g., public.jpeg - kUTTypeJPEG) 
     // <MobileCoreServices/UTCoreTypes.h> 

     CFStringRef UTI = CGImageSourceGetType(imageSource); 

     CFRelease(imageSource); 
    } 

    imageSource = nil;