objective-c uiimage exc-bad-access cgimageref

objective c - Objetivo C: ¿Cómo convertir CGImageRef a UIImageView?



objective-c exc-bad-access (3)

El problema está en [ZXImage imageWithMatrix: result], está creando CGImage y antes de asignarlo a ZXImage lo que aumentará su conteo de retención, liberará el CGImage mediante CFRelease.

Para solucionar este problema, reemplace el método de matriz + (ZXImage *) imageWithMatrix: (ZXBitMatrix *) con la implementación a continuación.

+ (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; }

Estoy usando el marco XZINGObjC para crear una EAN-Barcode-Image. Siguiendo la documentación, lo estoy haciendo como

//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; }

¡Funciona, si paso por este código usando puntos de interrupción! Sin embargo, creo que en algún momento una imagen no está lista para su uso? Pero no puedo encontrar la razón.

Lo que probé:

  • utilizando imageRef y uiImage como variables locales (EXC_BAD_ACCESS CRASH)
  • intenté esa operación en un hilo de fondo (EXC_BAD_ACCESS CRASH)

Lo mismo aquí, cada solución funcionaba si usaba puntos de interrupción y avanzaba línea por línea a través del código. ¿Cuál es mi error aquí? ¿Algunas ideas? ¡Gracias por adelantado!


Después de algunos intentos y errores de programación, pude solucionar el problema reemplazando las siguientes líneas

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

con

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

Aún así, no sé por qué? Estoy bastante seguro de que algo no está CGImageRef en la memoria o quizás el CGImageRef no está listo si trato de convertirlo a UIImage .


Para las personas que escriben Swift, encuentro el mismo problema que longilong describió. La respuesta estaba en los proyectos de ejemplo del objetivo C ZXingObjC. Recuerde: esto es para generar un código de barras solamente.

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") } }