iOS Question Crop a QR from a bitmap

yiankos1

Well-Known Member
Licensed User
Longtime User
Hello team,

I use this code to get the rect of a QR code from an image and then i want to save it as a new image (just the QR).

B4X:
Sub fileQR(bmp As Bitmap)
    Dim no As NativeObject = Me
    Dim res As List = no.RunMethod("detectRectQR:", Array(bmp))
    For Each feature As NativeObject In res

            Dim CGRect As Object = feature.GetField("bounds").RunMethod("CGRectValue", Null)

            Dim b As Bitmap
            
            b=no.RunMethod("ImageInRect::",Array(bmp,CGRect))

            Dim Out As OutputStream
            Out = File.OpenOutput(xui.DefaultFolder, "pass.png", False)
            b.WriteToStream(Out, 100, "PNG")
            Out.Close
    Next
End Sub

#if OBJC
    @import CoreImage;
    - (NSArray*) detectRectQR: (UIImage*)img {
    int exifOrientation;
    switch (img.imageOrientation) {
      case UIImageOrientationUp:
      exifOrientation = 1;
      break;
      case UIImageOrientationDown:
      exifOrientation = 3;
      break;
      case UIImageOrientationLeft:
      exifOrientation = 8;
      break;
      case UIImageOrientationRight:
      exifOrientation = 6;
      break;
      case UIImageOrientationUpMirrored:
      exifOrientation = 2;
      break;
      case UIImageOrientationDownMirrored:
      exifOrientation = 4;
      break;
      case UIImageOrientationLeftMirrored:
      exifOrientation = 5;
      break;
      case UIImageOrientationRightMirrored:
      exifOrientation = 7;
      break;
      default:
      break;
    }
    
    NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh };
    CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeQRCode  context:nil options:detectorOptions];
    
    NSArray *features = [faceDetector featuresInImage:[CIImage imageWithCGImage:img.CGImage]
      options:@{CIDetectorImageOrientation:[NSNumber numberWithInt:exifOrientation]}];
    
      if (features != nil && features.count > 0) {
        for (CIQRCodeFeature* qrFeature in features) {
            NSLog(@"QRFeature.messageString : %@ ", qrFeature.messageString);
        
        }
    }
      return features;
    
    }
    

-(UIImage*)ImageInRect: (UIImage*)image :(CGRect)rect
{
UIImage * LandscapeImage = image;
UIImage * PortraitImage = [[UIImage alloc] initWithCGImage: LandscapeImage.CGImage
                                                     scale: 1.0
                                               orientation: UIImageOrientationLeft];
CGImageRef imageRef = CGImageCreateWithImageInRect([PortraitImage CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return img;
}
#end if

The problem is that code does not crop the QR code, but another random rect from that image.
What is the problem with this code?

Thank you for your time.
 
Solution
I don't think that a rect is 'random'. A problem maybe in coordinates, exactly in y.
Dim CGRect As Object = feature.GetField("bounds").RunMethod("CGRectValue", Null)
(0, 0) is left-bottom point, not left-top. Try to change y.

At first, you need to know a height of original bitmap (let's name it hBitmap).
Then let's convert CGRect to values.
B4X:
        Dim no As NativeObject
        Dim list As List = no.ArrayFromRect (CGRect)
After this we can change y
B4X:
        CGRect = no.MakeRect (list.Get (0), hBitmap - (list.Get (1) + list.Get (3)), list.Get (2), list.Get (3))

I tested for portrait QR orientation. About other orientations - no idea.

Semen Matusovskiy

Well-Known Member
Licensed User
I don't think that a rect is 'random'. A problem maybe in coordinates, exactly in y.
Dim CGRect As Object = feature.GetField("bounds").RunMethod("CGRectValue", Null)
(0, 0) is left-bottom point, not left-top. Try to change y.

At first, you need to know a height of original bitmap (let's name it hBitmap).
Then let's convert CGRect to values.
B4X:
        Dim no As NativeObject
        Dim list As List = no.ArrayFromRect (CGRect)
After this we can change y
B4X:
        CGRect = no.MakeRect (list.Get (0), hBitmap - (list.Get (1) + list.Get (3)), list.Get (2), list.Get (3))

I tested for portrait QR orientation. About other orientations - no idea.
 
Last edited:
Upvote 2
Solution
Top