2011-09-02 7 views

Respuesta

15

utilicé respuesta Mats para construir una categoría simple en NSData que me dice si su contenido es JPEG o PNG basado en sus primeros 4 bytes:

@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 

Y entonces, simplemente hacer una:

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

Simplemente quiero agregar que no todos los archivos JPEG tienen el cuarto byte como e0. Resulta que hay varios "subtipos" hechos por varias compañías. Ver http://www.garykessler.net/library/file_sigs.html para al menos una lista parcial de ellos. En base a lo que he visto hasta ahora, parece que tienen consistentemente los primeros tres bytes como se mencionó anteriormente, y ningún otro tipo de archivo parece usar esos mismos tres bytes, pero no sé si esto está escrito en piedra en cualquier lugar . –

1

Aquí hay una versión Swift de la respuesta de la @ de 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

puede crear CGImageSourceRef y luego pedir para el tipo de imagen

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; 
Cuestiones relacionadas