Dynamsoft / capture-vision-react-native-samples

Dynamsoft Capture Vision React-Native SDK Samples
https://www.dynamsoft.com/capture-vision/docs/introduction/
Other
15 stars 7 forks source link

DCVCameraView styling support #29

Closed chernandez-bunnings closed 6 months ago

chernandez-bunnings commented 1 year ago

Hello,

Please label this query accordingly, as I could only submit an issue.

I was wondering if there is way (maybe not documented yet) to style the scanRegion and overlay look. Currently I could not find any info in the documentation.

From the (web demo) I can see the reader has a different look, so bearing in mind the differences between the APIs, theoretically this could possible, but not supported yet?

So I am wondering if there is any chance to support this functionality? I would like to make scan region with a border radius, different border colour and a darker masking background.

Dynamsoft-Henry commented 1 year ago

Hello @chernandez-bunnings

Currently, we don't support editing the style of scan region. You can use the property scanRegionVisible to hide it and draw a new one. Please let us know if you have difficulty on drawing your own scan region.

For the requirements on overlays, we have a method setOverlayColour(int fillARGB, int strokeARGB) in native Android and iOS SDK but it is not available on React Native edition. You can set the stroke and fill colors via the method. The other style settings are not available now. Is this method meet your requirement? If this method is enough, we can add it to the next version (A new version needs approximately 1-2 weeks).

chernandez-bunnings commented 1 year ago

Hello @Dynamsoft-Henry,

Thank you for your prompt response.

Could you please point me to the documentation of how to draw my own scanRegion?

Because I was not able to change the look of it, I was using a similar approach of hiding the scanRegion and including react-native-hole-view as an attempt to get the required look. However, the task of matching position between the hole view and the scanRegion proved to be problematic as they don't align exactly, resulting in a "misleading hole view" for the scanRegion where the bottom section of the hole is outside of the scanRegion and won't be a good visual indicator to align a barcode for scanning purposes.

As an FYI, I tried multiple approaches for the scanRegion props using regionMeasuredByPercentage true and false.

This image shows the issue. For that screenshot I made the scanRegion visible.

Regarding the overlay methods it would be nice to have them exposed in the RN SDK, but they are not necessary currently for my own use case, as I am not displaying the overlay when a barcode has been detected by the reader; but requirements may change and having that level of customisation may come handy, if not for me, perhaps other users?

Dynamsoft-Henry commented 1 year ago

Hello @chernandez-bunnings

The scanRegion property in our SDK is calculated by the video-streaming coordinate system. When you are trying to draw a customized "scanRegion", you have to transform the coordinates into the view coordinate system. For example, on my phone, the view size is 21001152 but the video size is 19201080 when using 1080P video steaming. They have different shapes.

If you are using x, y, width and height to draw a scanRegion, you can use the following formula to calculate the coordinates:

if viewHeight / viewWidth <= 1920 1080 float x = viewWidth (region.regionLeft/100); float y = 1920 (region.regionTop)/100 (viewWidth/1080) - (1920 (viewWidth/1080) - viewHeight)/2; float width = viewWidth ((region.regionRight - region.regionLeft)/100); float height = (1920 (region.regionBottom - (float)region.regionTop)/100) (viewWidth/1080);

if viewHeight / viewWidth > 1920 1080 float x = 1080 (region.regionLeft/100) (viewHeight/1920) -(1080 (viewHeight/1920)-viewWidth)/2; float y = viewHeight (region.regionTop/100); float width = (1080 (region.regionRight - region.regionLeft)/100) (viewHeight/1920); float height = viewHeight ((region.regionBottom - region.regionTop)/100);

We will add new APIs to support style settings and coordinate calculating in the future. Currently, please try the above solutions.

chernandez-bunnings commented 1 year ago

Hello @Dynamsoft-Henry

Thank you for sharing this.

Unfortunately after implementing this transformation logic, the "regions" still won't align. The misalignment is not as bad as before, but still not a perfect match. I'm wondering if pixel ratio | screen densities | video resolution of devices may be the reason.

I'm sharing screenshots of 3 different devices to illustrate the issue as the solution does not scale correctly. As well you will find the source code of this transformation logic.

iPhone 12 Pro Nothing Phone Pixel 5
const VIDEO_STREAM_HEIGHT_1920 = 1920
const VIDEO_STREAM_WIDTH_1080 = 1080

export const getTransformedViewCoordinates = ({
  scanRegion,
  viewWidth,
  viewHeight,
  borderRadius,
}: ScanRegionProps) => {
  const isSmallerShape =
    viewHeight / viewWidth <= VIDEO_STREAM_HEIGHT_1920 * VIDEO_STREAM_WIDTH_1080

  return isSmallerShape
    ? {
        x: viewWidth * (scanRegion.regionLeft / 100),
        y:
          VIDEO_STREAM_HEIGHT_1920 *
            (scanRegion.regionTop / 100) *
            (viewWidth / VIDEO_STREAM_WIDTH_1080) -
          (VIDEO_STREAM_HEIGHT_1920 * (viewWidth / 1080) - viewHeight) / 2,
        width:
          viewWidth * ((scanRegion.regionRight - scanRegion.regionLeft) / 100),
        height:
          VIDEO_STREAM_HEIGHT_1920 *
          ((scanRegion.regionBottom - scanRegion.regionTop) / 100) *
          (viewWidth / VIDEO_STREAM_WIDTH_1080),
        borderRadius,
      }
    : {
        x:
          VIDEO_STREAM_WIDTH_1080 *
            (scanRegion.regionLeft / 100) *
            (viewHeight / VIDEO_STREAM_HEIGHT_1920) -
          (VIDEO_STREAM_WIDTH_1080 * (viewHeight / VIDEO_STREAM_HEIGHT_1920) -
            viewWidth) /
            2,
        y: viewHeight * (scanRegion.regionTop / 100),
        width:
          ((VIDEO_STREAM_WIDTH_1080 *
            (scanRegion.regionRight - scanRegion.regionLeft)) /
            100) *
          (viewHeight / VIDEO_STREAM_HEIGHT_1920),
        height:
          viewHeight * ((scanRegion.regionBottom - scanRegion.regionTop) / 100),
        borderRadius,
      }
}

Special note (after writing original response): I tried the sample app to verify scanRegion behaviour. I could confirm it is not working correctly in iOS. It seems to only work treating the region as percentages, when regionMeasuredByPercentage is true. Setting this prop to false or 0 does not change how the region is treated. I even tried updating the SDK dynamsoft-capture-vision-react-native from 1.1.5 to 1.1.7. Also the region looks slightly different as it is missing the dark translucent background, it has in Android.

iOS

Android

both versions have the region set as

 let region = {
      regionTop: 30,
      regionLeft: 16,
      regionBottom: 50,
      regionRight: 50,
      regionMeasuredByPercentage: 0,
    };
Dynamsoft-Henry commented 1 year ago

Hi @chernandez-bunnings

Thanks for reporting the issues.

We have developed a sample that shows how to draw the scan region. Currently, it is uploaded to the scanRegionSample branch: https://github.com/Dynamsoft/capture-vision-react-native-samples/tree/scanRegionSample. The sample still need some test before handled. I think we can finish it tomorrow.

For the issues on regionMeasureByPercentage parameter and scan region background. We will try our best to release the debugged version tomorrow.

chernandez-bunnings commented 1 year ago

Hello @Dynamsoft-Henry

Thank you for creating the sample.

I tried the solution and I am sharing screenshots of three devices. The region alignment is still wrong in the sample app.

In iOS as the regionMeasureByPercentage is set to false, it does not display the region (although it should be visible, since scanRegionVisible is set to true)

Nothing Phone

Pixel 5

iPHone 13 Pro

These builds are from the scanRegionSample branch and source has not been modified.

Dynamsoft-Henry commented 1 year ago

Hi @chernandez-bunnings

There exists some bugs in the current version of dynamsoft-capture-vision-react-native package. We are debugging them and tending to release a new version today.

Dynamsoft-Henry commented 1 year ago

Hi @chernandez-bunnings

We released a new version.

"dynamsoft-capture-vision-react-native": "^1.1.8"

Would you like to try the scanRegionSample branch again with the new version?

chernandez-bunnings commented 1 year ago

Hello @Dynamsoft-Henry,

Thanks addressing the issues. I can confirm that I'm able to align the regions after updating the camera sdk to version 1.1.8

I will be waiting to the future sdk version where there is support to scanRegion styling and coordinates calculation directly from the new APIs. For now I will be using this workaround.

Cheers.

Dynamsoft-Henry commented 1 year ago

Hello @chernandez-bunnings

Good to know the new version works for you.

Our plans for the new features are as follow:

  1. Scan Region styling: We will support the settings of stroke width, colour. The border-radius is not included in the current design. This feature will be included in a significant update, which will take a few months.
  2. Coordinate calculation: This feature is definitely in the requirement pool. However, it is still not confirmed when to add it. At the latest, this feature will be added to the significant update mentioned above.