I have been playing around with OpenCV (https://docs.opencv.org/3.3.0/index.html) on Android quite a bit these days. While I am using OpenCV for image processing and image recognition work (using caffe bridge), I wanted to implement a UX scenario with dynamic magnification when a user is interacting with an image. An example of this UX is seen below:
You can see this kind of UX on iOS when trying to select a text. This is the equivalent for selecting a part of the image. After trying out a bit, I figured we could do with some simple lines of code as follows:
Mat img = ...; // the source image is read into this Mat
int sz = .. ; // size of zoomed area in pixels
int sf = 2 ; // the scale factor
int scaledFactor = sz * sf; // this would be the total width of the zoomed area
int mxX = mnX + scaledFactor;
int mxY = mnY + scaledFactor;
// the centre of the circle depicting the zoom
Point circleCenter = new Point((mxX-mnX)/2, (mxY-mnY)/2);
// the source rectangle
Rect rect = new Rect(mnHX, mnHY, sz, sz);
// the scaled rectangle
Rect scaledRect = new Rect(mnX, mnY, scaledFactor, scaledFactor);
Mat roiFrame = new Mat(img, rect); // get the are of interest to magnify
Mat scaledFrame = new Mat(roiFrame.rows()*sf, roiFrame.cols()*sf, img.type());
Mat circleMask = new Mat(roiFrame.rows()*sf, roiFrame.cols()*sf, img.type());
// create a circular mask
rectangle(circleMask, new Point(0, 0), new Point(scaledFactor, scaledFactor), BLACK, -1);
circle(circleMask, circleCenter, sz, WHITE, -1);
// zoom the rectangular area
resize(roiFrame, scaledFrame, new Size(), sf, sf, INTER_LINEAR);
// now copy the zoomed area into the source image applying the circular mask
scaledFrame.copyTo(img.submat(scaledRect), circleMask);
// indicative circle
circle(img, new Point((mxX+mnX)/2, (mxY+mnY)/2), sz, GREEN, 1);
// cleanup ..
roiFrame.release();
scaledFrame.release();
circleMask.release();
The above code is essentially a fast way to get a source rectangular area on the screen where a user is interacting, scale that area to a factor as needed, then apply a circular mask to give an effect of magnifying glass, then copy this back on to the source image so that it overlays to give a smooth UX with dynamic magnification when selecting a portion of the image.
No comments:
Post a Comment