Diễn giải siêu dữ liệu XMP trong ALAssetRepresentation


95

Khi người dùng thực hiện một số thay đổi (cắt xén, loại bỏ mắt đỏ, ...) đối với ảnh trong ứng dụng Photos. tích hợp sẵn trên iOS, những thay đổi đó sẽ không được áp dụng cho ảnh được fullResolutionImagetrả về tương ứng ALAssetRepresentation.

Tuy nhiên, những thay đổi được áp dụng cho thumbnailfullScreenImagetrả về bởi ALAssetRepresentation. Hơn nữa, thông tin về các thay đổi được áp dụng có thể được tìm thấy trong ALAssetRepresentationtừ điển siêu dữ liệu của 'thông qua khóa @"AdjustmentXMP".

Tôi muốn áp dụng những thay đổi này cho fullResolutionImagebản thân để duy trì tính nhất quán. Tôi đã phát hiện ra rằng trên iOS6 + CIFilter 's filterArrayFromSerializedXMP: inputImageExtent:error:có thể chuyển đổi này XMP siêu dữ liệu tới một mảng của CIFilter' s:

ALAssetRepresentation *rep; 
NSString *xmpString = rep.metadata[@"AdjustmentXMP"];
NSData *xmpData = [xmpString dataUsingEncoding:NSUTF8StringEncoding];

CIImage *image = [CIImage imageWithCGImage:rep.fullResolutionImage];

NSError *error = nil;
NSArray *filterArray = [CIFilter filterArrayFromSerializedXMP:xmpData 
                                             inputImageExtent:image.extent 
                                                        error:&error];
if (error) {
     NSLog(@"Error during CIFilter creation: %@", [error localizedDescription]);
}

CIContext *context = [CIContext contextWithOptions:nil];

for (CIFilter *filter in filterArray) {
     [filter setValue:image forKey:kCIInputImageKey];
     image = [filter outputImage];
}

Tuy nhiên, điều này chỉ hoạt động đối với một số bộ lọc (cắt xén, tự động cải tiến) chứ không hiệu quả với những bộ lọc khác như loại bỏ mắt đỏ. Trong những trường hợp này, CIFilterchúng không có tác dụng rõ ràng. Do đó, câu hỏi của tôi:

  • Có ai biết về một cách để tạo ra loại bỏ mắt đỏ CIFilterkhông? (Theo một cách nhất quán với ứng dụng Photos. Bộ lọc có phím kCIImageAutoAdjustRedEyelà không đủ. Ví dụ: nó không lấy tham số cho vị trí của mắt.)
  • Có khả năng tạo và áp dụng các bộ lọc này trong iOS 5 không?

Liên kết này là một câu hỏi Stackoverflow khác cung cấp một thuật toán cho mắt đỏ. Nó không nhiều nhưng đó là một sự khởi đầu. stackoverflow.com/questions/133675/red-eye-reduction-algorithm
Roecrew

Trên iOS 7, mã được liệt kê áp dụng chính xác bộ lọc loại bỏ mắt đỏ (bộ lọc nội bộ CIRedEyeCorrections).
paiv

Câu trả lời:


2
ALAssetRepresentation* representation = [[self assetAtIndex:index] defaultRepresentation];

// Create a buffer to hold the data for the asset's image
uint8_t *buffer = (Byte*)malloc(representation.size); // Copy the data from the asset into the buffer
NSUInteger length = [representation getBytes:buffer fromOffset: 0.0  length:representation.size error:nil];

if (length==0)
    return nil;

// Convert the buffer into a NSData object, and free the buffer after.

NSData *adata = [[NSData alloc] initWithBytesNoCopy:buffer length:representation.size freeWhenDone:YES];

// Set up a dictionary with a UTI hint. The UTI hint identifies the type
// of image we are dealing with (that is, a jpeg, png, or a possible
// RAW file).

// Specify the source hint.

NSDictionary* sourceOptionsDict = [NSDictionary dictionaryWithObjectsAndKeys:

(id)[representation UTI], kCGImageSourceTypeIdentifierHint, nil];

// Create a CGImageSource with the NSData. A image source can
// contain x number of thumbnails and full images.

CGImageSourceRef sourceRef = CGImageSourceCreateWithData((CFDataRef) adata,  (CFDictionaryRef) sourceOptionsDict);

[adata release];

CFDictionaryRef imagePropertiesDictionary;

// Get a copy of the image properties from the CGImageSourceRef.

imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(sourceRef,0, NULL);

CFNumberRef imageWidth = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelWidth);

CFNumberRef imageHeight = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelHeight);

int w = 0;

int h = 0;

CFNumberGetValue(imageWidth, kCFNumberIntType, &w);

CFNumberGetValue(imageHeight, kCFNumberIntType, &h);

// Clean up memory

CFRelease(imagePropertiesDictionary);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.