我正在使用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;
}
如果我使用断点逐步执行此代码,它可以工作!但是,我认为在某些时候图像还没有准备好使用?!但我找不到原因。
我尝试了什么:
imageRef
和uiImage
作为局部变量(EXC_BAD_ACCESS CRASH)同样,如果我使用断点并逐行逐步执行代码,每个解决方案都有效。这里我的错误是什么?有任何想法吗?提前谢谢!
答案 0 :(得分:11)
经过一些尝试和错误编程后,我可以通过替换以下行来解决问题
CGImageRef imageRef = [[ZXImage imageWithMatrix:result] cgimage];
UIImage* uiImage = [[UIImage alloc] initWithCGImage:imageRef]; //<--CRASH
带
UIImage* uiImage = [[UIImage alloc] initWithCGImage:[[ZXImage imageWithMatrix:result] cgimage]];
仍然,我不知道为什么?!我很确定内存中没有内容,或者如果我尝试转换,CGImageRef
可能还没有准备就绪它到UIImage
。
答案 1 :(得分:2)
问题出在[ZXImage imageWithMatrix:result]中,它正在创建CGImage,在将它分配给ZXImage之前会增加其保留计数,它会通过CFRelease释放CGImage。
要解决此问题,请将+(ZXImage *)imageWithMatrix:(ZXBitMatrix *)矩阵方法替换为以下实现。
+ (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;
}
答案 2 :(得分:2)
对于编写Swift的人来说,我遇到了龙陇描述的同样问题。答案是在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")
}
}