1

这里的高级是我在我的 iOS 应用程序中尝试做的事情:

  1. 允许用户从他们的照片库中选择资产
  2. 共享一个 URL,我的应用程序外部的实体可以使用该 URL 来请求相同的资产
  3. 我的应用程序正在运行一个网络服务器(CocoaHTTPServer),它能够将该数据提供给请求实体
  4. 我故意使用 ALAssetRepresentation getBytes:fromOffset:length:error: 实现了这一点,认为我可以避免以下头痛:
    • 在提供图像之前编写图像的本地副本(然后必须管理本地副本)
    • 将所有图像数据放入内存
    • 可能会降低性能,在提供任何图像之前等待获得整个图像

它的工作水平很高,但有一个问题。在某些情况下,图像的方向不正确。

这是一个众所周知的问题,但解决方案通常似乎需要从 ALAssetRepresentation 创建 CGImage 或 UIImage。一旦我这样做,它就消除了我使用方便的 ALAssetRepresentation getBytes:fromOffset:length:error: 方法的能力。

如果有一种方法可以继续使用这种方法但方向正确,那就太酷了。如果没有,我将不胜感激有关下一个最佳方法的任何建议。谢谢!

以下是一些相关的方法:

- (id)initWithAssetURL:(NSURL *)assetURL forConnection:(MyHTTPConnection *)parent{
if((self = [super init]))
{
    HTTPLogTrace();

    // Need this now so we can use it throughout the class
    self.connection = parent;
    self.assetURL = assetURL;

    offset = 0;

    // Grab a pointer to the ALAssetsLibrary which we can persistently use
    self.lib = [[ALAssetsLibrary alloc] init];

    // Really need to know the size of the asset, but we will also set a property for the ALAssetRepresentation to use later
    // Otherwise we would have to asynchronously look up the asset again by assetForURL
    [self.lib assetForURL:assetURL
         resultBlock:^(ALAsset *asset) {
             self.assetRepresentation = [asset defaultRepresentation];
             self.assetSize = [self.assetRepresentation size];
             // Even though we don't really have any data, this will enable the response headers to be sent
             // It will call our delayResponseHeaders method, which will now return NO, since we've set self.repr
             [self.connection responseHasAvailableData:self];
         }
        failureBlock:^(NSError *error) {
            // recover from error, then
            NSLog(@"error in the failureBlock: %@",[error localizedDescription]);
        }];
}
return self;
}

- (NSData *)readDataOfLength:(NSUInteger)lengthParameter{
HTTPLogTrace2(@"%@[%p]: readDataOfLength:%lu", THIS_FILE, self, (unsigned long)lengthParameter);

NSUInteger remaining = self.assetSize - offset;
NSUInteger length = lengthParameter < remaining ? lengthParameter : remaining;

Byte *buffer = (Byte *)malloc(length);
NSError *error;

NSUInteger buffered = [self.assetRepresentation getBytes:buffer fromOffset:offset length:length error:&error];
NSLog(@"Error: %@",[error localizedDescription]);
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];

// now that we've read data of length, update the offset for the next invocation
offset += length;

return data;
}
4

0 回答 0