3

RPBroadcastSampleHandler で CMSampleBuffer から NSData への変換を処理しているときに、メモリ許容量を超えるエラーが発生しました。エラー コード: スレッド 7: EXC_RESOURCE RESOURCE_TYPE_MEMORY (制限 = 50 MB、未使用 = 0x0)

1920x1440の大きな画像をバイナリに変換してソケットサーバーに送信する機能を処理しています。サイズを 1200x900 に変更しようとしましたが、何も機能しませんでした。

この問題に対処するために 1 週​​間を費やしましたが、役に立ちませんでした。私は次のことを試しました: ここからの指示で画像のサイズを変更します: https://nshipster.com/image-resizing/

  1. SampleBuffer から UIImage オブジェクトを取得し、圧縮品質が最も低い jpegData に変換します。
    func getDataFromCMSampleBuffer (sampleBuffer: CMSampleBuffer) -> Data? {
        if CMSampleBufferDataIsReady (sampleBuffer),
            let pixelBuffer = CMSampleBufferGetImageBuffer (sampleBuffer) {
            let ciImage = CIImage (cvImageBuffer: pixelBuffer)
            let image = UIImage (ciImage: ciImage)
            return (image.jpegData (compressionQuality: 0.0)) // Error Thread 7: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)
        }
        return nil
    }
  1. NSData に変換する前に、CMSampleBuffer から UIImage オブジェクトのサイズを変更します。
    let renderer = UIGraphicsImageRenderer (size: CGSize (width: 1200, height: 900))
    return renderer.image {(context) in
        image.draw (in: CGRect (origin: .zero, size: size)) // Error Thread 7: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)
    }

または

    UIGraphicsBeginImageContextWithOptions (CGSizeMake (newWidth, newHeight), NO, 0);
    [sourceImage drawInRect: CGRectMake (0, 0, 1200, 900)]; //// Error Thread 7: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)
    UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext ();
    UIGraphicsEndImageContext ();
  1. NSData に変換する前に、CMSampleBuffer からイメージ ビットマップを取得します。
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB ();
    CGContextRef context = CGBitmapContextCreate (rgbBuffer, width, height, 8, width * bytesPerPixel, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
    CGImageRef quartzImage = CGBitmapContextCreateImage (context); // Thread 7 error: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)
    UIImage * image = [UIImage imageWithCGImage: quartzImage];
  1. NSData に変換する前に CIImage をスケーリングする
    CIFilter *filter = [CIFilter filterWithName:@"CILanczosScaleTransform"];
    [filter setValue:image forKey:kCIInputImageKey];
    [filter setValue:[NSNumber numberWithDouble:0.2] forKey:kCIInputScaleKey];
    [filter setValue:@1.0 forKey:kCIInputAspectRatioKey];
    CIImage *img = (CIImage*)[filter valueForKey:kCIOutputImageKey];

...
    CIContext *context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer: @NO}];

    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();

    [context render:img toBitmap:rawData rowBytes:width*kComponentsPerPixel bounds:img.extent format:kCIFormatRGBA8 colorSpace:rgb];// Thread 7 error: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)

    CGDataProviderRef provider = CGDataProviderCreateWithData(nil, rawData, memsize, releasePixels);

50MB のメモリを超えずに CMSampleBuffer から NSData 画像に変換する方法はありますか? 画質はあまり低下しません。または、50MB を超えるメモリを使用しない大きな画像のサイズを変更する方法はありますか?

私が与えるアドバイスはとても感謝しています。

4

0 に答える 0