6

我正在使用XZINGObjC框架来创建 EAN-Barcode-Image。按照文档,我正在这样做

 //in viewDidAppear

 //XZING: create Matrix
 NSString* eanString = @"1234567890123";  //sth. like that
 ZXBitMatrix* result = [writer encode:eanString
                              format:kBarcodeFormatEan13
                               width:500
                              height:500
                               error:&error];
if (result) {
      //XZING: convert matrix to CGImageRef
      CGImageRef imageRef = [[ZXImage imageWithMatrix:result] cgimage]; 

      //CRASHLINE HERE!! (this is NOT in the XZING documentation, but i cannot figure out the issue!)
      UIImage* uiImage = [[UIImage alloc] initWithCGImage:imageRef];  //<--CRASH: EXC_BAD_ACCESS

      if(image != nil){
          //assigning image to ui
          self.barCodeImageView.image = uiImage;   
      }

如果我使用断点单步执行此代码,它就可以工作!但是,我认为在某些时候图像还没有准备好使用?!但我找不到原因。

我尝试了什么:

  • 使用imageRefuiImage作为局部变量(EXC_BAD_ACCESS CRASH)
  • 在后台线程中尝试了该操作(EXC_BAD_ACCESS CRASH)

同样在这里,如果我使用断点并逐行执行代码,则每个解决方案都有效。我的错误是什么?有任何想法吗?提前致谢!

4

3 回答 3

13

经过一些尝试和错误编程后,我可以通过替换以下行来解决问题

  CGImageRef imageRef = [[ZXImage imageWithMatrix:result] cgimage]; 
  UIImage* uiImage = [[UIImage alloc] initWithCGImage:imageRef];  //<--CRASH

 UIImage* uiImage = [[UIImage alloc] initWithCGImage:[[ZXImage imageWithMatrix:result] cgimage]];

还是不知道为什么?! 我很确定内存中没有某些内容,或者CGImageRef如果我尝试将其转换为UIImage.

于 2014-05-12T13:36:57.057 回答
2

问题出在 [ZXImage imageWithMatrix:result] 中,它正在创建 CGImage,在将其分配给 ZXImage 之前,这将增加其保留计数,它正在通过 CFRelease 释放 CGImage。

要解决此问题,请将 + (ZXImage *)imageWithMatrix:(ZXBitMatrix *)matrix 方法替换为以下实现。

+ (ZXImage *)imageWithMatrix:(ZXBitMatrix *)matrix {
    int width = matrix.width;
    int height = matrix.height;
    int8_t *bytes = (int8_t *)malloc(width * height * 4);
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            BOOL bit = [matrix getX:x y:y];
            int8_t intensity = bit ? 0 : 255;
            for(int i = 0; i < 3; i++) {
                bytes[y * width * 4 + x * 4 + i] = intensity;
            }
            bytes[y * width * 4 + x * 4 + 3] = 255;
        }
    }

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef c = CGBitmapContextCreate(bytes, width, height, 8, 4 * width, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);

    CGImageRef image = CGBitmapContextCreateImage(c);


    ZXImage *zxImage = [[ZXImage alloc] initWithCGImageRef:image];
    CFRelease(colorSpace);
    CFAutorelease(image);
    CFRelease(c);
    free(bytes);
    return zxImage;
}
于 2014-07-13T09:26:55.373 回答
2

对于编写 Swift 的人,我遇到了 longilong 描述的相同问题。答案在 ZXingObjC 目标 C 示例项目中。请记住:这仅用于生成条形码。

internal func encodeBarcode(){
    let writer : ZXMultiFormatWriter! = ZXMultiFormatWriter()
    var result: ZXBitMatrix!
    let hint: ZXEncodeHints! = ZXEncodeHints()

    do {
        hint.margin = 0
        result = try writer.encode("Example String", format: kBarcodeFormatAztec, width: 500, height: 500, hints: hint)

        **let rawBarcode: ZXImage = ZXImage(matrix: result)
        barcodeUIImage.image = UIImage(CGImage: rawBarcode.cgimage)**

    } catch {
        print("failed to generate barcode")
    }
}
于 2015-12-23T14:26:24.010 回答