feat(windows): added barcode scanning support (#2930)

Build:
* Fixed issue with edit and continue debug symbols
* Fixed ReactNativeCameraCPP61 builds
* Added dependency on huycn.zxingcpp.winrt for barcode support

ReactNativeCameraCPP RNCamera component:
* Added onBarCodeRead event support
* Added barCodeScannerEnabled property support
* Added barCodeTypes property support
* Added barCodeReadIntervalMS property to alter how often the scan
  occurs when enabled

ReactNativeCameraCPP RNCamera module:
* Added BarCodeType constants

Other:
* Fixed intermittent issue with thread marshalling
* Re-ran clang formatting

Closes #2830
This commit is contained in:
Jon Thysell 2020-08-11 11:57:00 -07:00 committed by GitHub
parent bec91a4b5a
commit 2782a24d25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 734 additions and 529 deletions

View File

@ -1,217 +1,219 @@
#include "pch.h"
#include "CameraRotationHelper.h"
#include "CameraRotationHelper.g.cpp"
namespace winrt {
using namespace Windows::Devices::Enumeration;
using namespace Windows::Devices::Sensors;
using namespace Windows::Storage::FileProperties;
using namespace Windows::Graphics::Display;
} // namespace winrt
namespace winrt::ReactNativeCameraCPP::implementation {
CameraRotationHelper::CameraRotationHelper(EnclosureLocation location) {
m_cameraEnclosureLocation = location;
if (!IsEnclosureLocationExternal(m_cameraEnclosureLocation) && m_orientationSensor != nullptr) {
m_sensorOrientationChanged_revoker = m_orientationSensor.OrientationChanged(
winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
if (auto self = ref.get()) {
self->SimpleOrientationSensor_OrientationChanged(sender, args);
}
});
}
m_displayOrientationChanged_revoker = m_displayInformation.OrientationChanged(
winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
if (auto self = ref.get()) {
self->DisplayInformation_OrientationChanged(sender, args);
}
});
}
PhotoOrientation CameraRotationHelper::GetConvertedCameraCaptureOrientation() {
auto orientation = GetCameraCaptureOrientation();
return ConvertSimpleOrientationToPhotoOrientation(orientation);
}
SimpleOrientation CameraRotationHelper::GetCameraCaptureOrientation() {
if (IsEnclosureLocationExternal(m_cameraEnclosureLocation)) {
// Cameras that are not attached to the device do not rotate along with it, so apply no rotation
return SimpleOrientation::NotRotated;
}
// Get the device orientation offset by the camera hardware offset
auto deviceOrientation =
m_orientationSensor ? m_orientationSensor.GetCurrentOrientation() : SimpleOrientation::NotRotated;
auto result = SubtractOrientations(deviceOrientation, GetCameraOrientationRelativeToNativeOrientation());
// If the preview is being mirrored for a front-facing camera, then the rotation should be inverted
if (ShouldMirrorPreview()) {
result = MirrorOrientation(result);
}
return result;
}
SimpleOrientation CameraRotationHelper::GetCameraPreviewOrientation() {
if (IsEnclosureLocationExternal(m_cameraEnclosureLocation)) {
// Cameras that are not attached to the device do not rotate along with it, so apply no rotation
return SimpleOrientation::NotRotated;
}
// Get the app display rotation offset by the camera hardware offset
auto result = ConvertDisplayOrientationToSimpleOrientation(m_displayInformation.CurrentOrientation());
result = SubtractOrientations(result, GetCameraOrientationRelativeToNativeOrientation());
// If the preview is being mirrored for a front-facing camera, then the rotation should be inverted
if (ShouldMirrorPreview()) {
result = MirrorOrientation(result);
}
return result;
}
int CameraRotationHelper::GetCameraPreviewClockwiseDegrees() {
auto rotation = GetCameraPreviewOrientation();
return ConvertSimpleOrientationToClockwiseDegrees(rotation);
}
PhotoOrientation CameraRotationHelper::ConvertSimpleOrientationToPhotoOrientation(SimpleOrientation orientation) {
switch (orientation) {
case SimpleOrientation::Rotated90DegreesCounterclockwise:
return PhotoOrientation::Rotate90;
case SimpleOrientation::Rotated180DegreesCounterclockwise:
return PhotoOrientation::Rotate180;
case SimpleOrientation::Rotated270DegreesCounterclockwise:
return PhotoOrientation::Rotate270;
case SimpleOrientation::NotRotated:
default:
return PhotoOrientation::Normal;
}
}
int CameraRotationHelper::ConvertSimpleOrientationToClockwiseDegrees(SimpleOrientation orientation) {
switch (orientation) {
case SimpleOrientation::Rotated90DegreesCounterclockwise:
return 270;
case SimpleOrientation::Rotated180DegreesCounterclockwise:
return 180;
case SimpleOrientation::Rotated270DegreesCounterclockwise:
return 90;
case SimpleOrientation::NotRotated:
default:
return 0;
}
}
SimpleOrientation CameraRotationHelper::ConvertDisplayOrientationToSimpleOrientation(DisplayOrientations orientation) {
SimpleOrientation result;
switch (orientation) {
case DisplayOrientations::Landscape:
result = SimpleOrientation::NotRotated;
break;
case DisplayOrientations::PortraitFlipped:
result = SimpleOrientation::Rotated90DegreesCounterclockwise;
break;
case DisplayOrientations::LandscapeFlipped:
result = SimpleOrientation::Rotated180DegreesCounterclockwise;
break;
case DisplayOrientations::Portrait:
default:
result = SimpleOrientation::Rotated270DegreesCounterclockwise;
break;
}
// Above assumes landscape; offset is needed if native orientation is portrait
if (m_displayInformation.NativeOrientation() == DisplayOrientations::Portrait) {
result = AddOrientations(result, SimpleOrientation::Rotated90DegreesCounterclockwise);
}
return result;
}
SimpleOrientation CameraRotationHelper::SubtractOrientations(SimpleOrientation a, SimpleOrientation b) {
auto aRot = ConvertSimpleOrientationToClockwiseDegrees(a);
auto bRot = ConvertSimpleOrientationToClockwiseDegrees(b);
// Add 360 to ensure the modulus operator does not operate on a negative
auto result = (360 + (aRot - bRot)) % 360;
return ConvertClockwiseDegreesToSimpleOrientation(result);
}
SimpleOrientation CameraRotationHelper::MirrorOrientation(SimpleOrientation orientation) {
// This only affects the 90 and 270 degree cases, because rotating 0 and 180 degrees is the same clockwise and
// counter-clockwise
switch (orientation) {
case SimpleOrientation::Rotated90DegreesCounterclockwise:
return SimpleOrientation::Rotated270DegreesCounterclockwise;
case SimpleOrientation::Rotated270DegreesCounterclockwise:
return SimpleOrientation::Rotated90DegreesCounterclockwise;
}
return orientation;
}
SimpleOrientation CameraRotationHelper::AddOrientations(SimpleOrientation a, SimpleOrientation b) {
auto aRot = ConvertSimpleOrientationToClockwiseDegrees(a);
auto bRot = ConvertSimpleOrientationToClockwiseDegrees(b);
auto result = (aRot + bRot) % 360;
return ConvertClockwiseDegreesToSimpleOrientation(result);
}
SimpleOrientation CameraRotationHelper::ConvertClockwiseDegreesToSimpleOrientation(int orientation) {
switch (orientation) {
case 270:
return SimpleOrientation::Rotated90DegreesCounterclockwise;
case 180:
return SimpleOrientation::Rotated180DegreesCounterclockwise;
case 90:
return SimpleOrientation::Rotated270DegreesCounterclockwise;
case 0:
default:
return SimpleOrientation::NotRotated;
}
}
void CameraRotationHelper::SimpleOrientationSensor_OrientationChanged(IInspectable const &, IInspectable const &) {
if (m_orientationSensor.GetCurrentOrientation() != SimpleOrientation::Faceup &&
m_orientationSensor.GetCurrentOrientation() != SimpleOrientation::Facedown) {
// Only raise the OrientationChanged event if the device is not parallel to the ground. This allows users to take
// pictures of documents (FaceUp) or the ceiling (FaceDown) in portrait or landscape, by first holding the device in
// the desired orientation, and then pointing the camera either up or down, at the desired subject.
// Note: This assumes that the camera is either facing the same way as the screen, or the opposite way. For devices
// with cameras mounted
// on other panels, this logic should be adjusted.
m_orientationChangedEvent(*this, false);
}
}
void CameraRotationHelper::DisplayInformation_OrientationChanged(IInspectable const &, IInspectable const &) {
m_orientationChangedEvent(*this, true);
}
bool CameraRotationHelper::ShouldMirrorPreview() {
// It is recommended that applications mirror the preview for front-facing cameras, as it gives users a more natural
// experience, since it behaves more like a mirror
return (m_cameraEnclosureLocation.Panel() == Panel::Front);
}
SimpleOrientation CameraRotationHelper::GetCameraOrientationRelativeToNativeOrientation() {
// Get the rotation angle of the camera enclosure as it is mounted in the device hardware
auto enclosureAngle = ConvertClockwiseDegreesToSimpleOrientation(
static_cast<int>(m_cameraEnclosureLocation.RotationAngleInDegreesClockwise()));
// Account for the fact that, on portrait-first devices, the built in camera sensor is read at a 90 degree offset to
// the native orientation
if (m_displayInformation.NativeOrientation() == DisplayOrientations::Portrait &&
!IsEnclosureLocationExternal(m_cameraEnclosureLocation)) {
enclosureAngle = AddOrientations(SimpleOrientation::Rotated90DegreesCounterclockwise, enclosureAngle);
}
return enclosureAngle;
}
winrt::event_token CameraRotationHelper::OrientationChanged(Windows::Foundation::EventHandler<bool> const &handler) {
return m_orientationChangedEvent.add(handler);
}
void CameraRotationHelper::OrientationChanged(winrt::event_token const &token) noexcept {
m_orientationChangedEvent.remove(token);
}
} // namespace winrt::ReactNativeCameraCPP::implementation
#include "pch.h"
#include "CameraRotationHelper.h"
#include "CameraRotationHelper.g.cpp"
namespace winrt {
using namespace Windows::Devices::Enumeration;
using namespace Windows::Devices::Sensors;
using namespace Windows::Storage::FileProperties;
using namespace Windows::Graphics::Display;
} // namespace winrt
namespace winrt::ReactNativeCameraCPP::implementation {
CameraRotationHelper::CameraRotationHelper(EnclosureLocation location) {
m_cameraEnclosureLocation = location;
if (!IsEnclosureLocationExternal(m_cameraEnclosureLocation) && m_orientationSensor != nullptr) {
m_sensorOrientationChanged_revoker = m_orientationSensor.OrientationChanged(
winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
if (auto self = ref.get()) {
self->SimpleOrientationSensor_OrientationChanged(sender, args);
}
});
}
m_displayOrientationChanged_revoker = m_displayInformation.OrientationChanged(
winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
if (auto self = ref.get()) {
self->DisplayInformation_OrientationChanged(sender, args);
}
});
}
PhotoOrientation CameraRotationHelper::GetConvertedCameraCaptureOrientation() {
auto orientation = GetCameraCaptureOrientation();
return ConvertSimpleOrientationToPhotoOrientation(orientation);
}
SimpleOrientation CameraRotationHelper::GetCameraCaptureOrientation() {
if (IsEnclosureLocationExternal(m_cameraEnclosureLocation)) {
// Cameras that are not attached to the device do not rotate along with it, so apply no rotation
return SimpleOrientation::NotRotated;
}
// Get the device orientation offset by the camera hardware offset
auto deviceOrientation =
m_orientationSensor ? m_orientationSensor.GetCurrentOrientation() : SimpleOrientation::NotRotated;
auto result = SubtractOrientations(deviceOrientation, GetCameraOrientationRelativeToNativeOrientation());
// If the preview is being mirrored for a front-facing camera, then the rotation should be inverted
if (ShouldMirrorPreview()) {
result = MirrorOrientation(result);
}
return result;
}
SimpleOrientation CameraRotationHelper::GetCameraPreviewOrientation() {
if (IsEnclosureLocationExternal(m_cameraEnclosureLocation)) {
// Cameras that are not attached to the device do not rotate along with it, so apply no rotation
return SimpleOrientation::NotRotated;
}
// Get the app display rotation offset by the camera hardware offset
auto result = ConvertDisplayOrientationToSimpleOrientation(m_displayInformation.CurrentOrientation());
result = SubtractOrientations(result, GetCameraOrientationRelativeToNativeOrientation());
// If the preview is being mirrored for a front-facing camera, then the rotation should be inverted
if (ShouldMirrorPreview()) {
result = MirrorOrientation(result);
}
return result;
}
int CameraRotationHelper::GetCameraPreviewClockwiseDegrees() {
auto rotation = GetCameraPreviewOrientation();
return ConvertSimpleOrientationToClockwiseDegrees(rotation);
}
PhotoOrientation CameraRotationHelper::ConvertSimpleOrientationToPhotoOrientation(SimpleOrientation orientation) {
switch (orientation) {
case SimpleOrientation::Rotated90DegreesCounterclockwise:
return PhotoOrientation::Rotate90;
case SimpleOrientation::Rotated180DegreesCounterclockwise:
return PhotoOrientation::Rotate180;
case SimpleOrientation::Rotated270DegreesCounterclockwise:
return PhotoOrientation::Rotate270;
case SimpleOrientation::NotRotated:
default:
return PhotoOrientation::Normal;
}
}
int CameraRotationHelper::ConvertSimpleOrientationToClockwiseDegrees(SimpleOrientation orientation) {
switch (orientation) {
case SimpleOrientation::Rotated90DegreesCounterclockwise:
return 270;
case SimpleOrientation::Rotated180DegreesCounterclockwise:
return 180;
case SimpleOrientation::Rotated270DegreesCounterclockwise:
return 90;
case SimpleOrientation::NotRotated:
default:
return 0;
}
}
SimpleOrientation CameraRotationHelper::ConvertDisplayOrientationToSimpleOrientation(DisplayOrientations orientation) {
SimpleOrientation result;
switch (orientation) {
case DisplayOrientations::Landscape:
result = SimpleOrientation::NotRotated;
break;
case DisplayOrientations::PortraitFlipped:
result = SimpleOrientation::Rotated90DegreesCounterclockwise;
break;
case DisplayOrientations::LandscapeFlipped:
result = SimpleOrientation::Rotated180DegreesCounterclockwise;
break;
case DisplayOrientations::Portrait:
default:
result = SimpleOrientation::Rotated270DegreesCounterclockwise;
break;
}
// Above assumes landscape; offset is needed if native orientation is portrait
if (m_displayInformation.NativeOrientation() == DisplayOrientations::Portrait) {
result = AddOrientations(result, SimpleOrientation::Rotated90DegreesCounterclockwise);
}
return result;
}
SimpleOrientation CameraRotationHelper::SubtractOrientations(SimpleOrientation a, SimpleOrientation b) {
auto aRot = ConvertSimpleOrientationToClockwiseDegrees(a);
auto bRot = ConvertSimpleOrientationToClockwiseDegrees(b);
// Add 360 to ensure the modulus operator does not operate on a negative
auto result = (360 + (aRot - bRot)) % 360;
return ConvertClockwiseDegreesToSimpleOrientation(result);
}
SimpleOrientation CameraRotationHelper::MirrorOrientation(SimpleOrientation orientation) {
// This only affects the 90 and 270 degree cases, because rotating 0 and 180 degrees is the same clockwise and
// counter-clockwise
switch (orientation) {
case SimpleOrientation::Rotated90DegreesCounterclockwise:
return SimpleOrientation::Rotated270DegreesCounterclockwise;
case SimpleOrientation::Rotated270DegreesCounterclockwise:
return SimpleOrientation::Rotated90DegreesCounterclockwise;
}
return orientation;
}
SimpleOrientation CameraRotationHelper::AddOrientations(SimpleOrientation a, SimpleOrientation b) {
auto aRot = ConvertSimpleOrientationToClockwiseDegrees(a);
auto bRot = ConvertSimpleOrientationToClockwiseDegrees(b);
auto result = (aRot + bRot) % 360;
return ConvertClockwiseDegreesToSimpleOrientation(result);
}
SimpleOrientation CameraRotationHelper::ConvertClockwiseDegreesToSimpleOrientation(int orientation) {
switch (orientation) {
case 270:
return SimpleOrientation::Rotated90DegreesCounterclockwise;
case 180:
return SimpleOrientation::Rotated180DegreesCounterclockwise;
case 90:
return SimpleOrientation::Rotated270DegreesCounterclockwise;
case 0:
default:
return SimpleOrientation::NotRotated;
}
}
void CameraRotationHelper::SimpleOrientationSensor_OrientationChanged(IInspectable const &, IInspectable const &) {
if (m_orientationSensor.GetCurrentOrientation() != SimpleOrientation::Faceup &&
m_orientationSensor.GetCurrentOrientation() != SimpleOrientation::Facedown) {
// Only raise the OrientationChanged event if the device is not parallel to the ground. This allows users to take
// pictures of documents (FaceUp) or the ceiling (FaceDown) in portrait or landscape, by first holding the device in
// the desired orientation, and then pointing the camera either up or down, at the desired subject.
// Note: This assumes that the camera is either facing the same way as the screen, or the opposite way. For devices
// with cameras mounted
// on other panels, this logic should be adjusted.
m_orientationChangedEvent(*this, false);
}
}
void CameraRotationHelper::DisplayInformation_OrientationChanged(IInspectable const &, IInspectable const &) {
m_orientationChangedEvent(*this, true);
}
bool CameraRotationHelper::ShouldMirrorPreview() {
// It is recommended that applications mirror the preview for front-facing cameras, as it gives users a more natural
// experience, since it behaves more like a mirror
return (m_cameraEnclosureLocation.Panel() == Panel::Front);
}
SimpleOrientation CameraRotationHelper::GetCameraOrientationRelativeToNativeOrientation() {
// Get the rotation angle of the camera enclosure as it is mounted in the device hardware
auto enclosureAngle = ConvertClockwiseDegreesToSimpleOrientation(
static_cast<int>(m_cameraEnclosureLocation.RotationAngleInDegreesClockwise()));
// Account for the fact that, on portrait-first devices, the built in camera sensor is read at a 90 degree offset to
// the native orientation
if (m_displayInformation.NativeOrientation() == DisplayOrientations::Portrait &&
!IsEnclosureLocationExternal(m_cameraEnclosureLocation)) {
enclosureAngle = AddOrientations(SimpleOrientation::Rotated90DegreesCounterclockwise, enclosureAngle);
}
return enclosureAngle;
}
winrt::event_token CameraRotationHelper::OrientationChanged(Windows::Foundation::EventHandler<bool> const &handler) {
return m_orientationChangedEvent.add(handler);
}
void CameraRotationHelper::OrientationChanged(winrt::event_token const &token) noexcept {
m_orientationChangedEvent.remove(token);
}
} // namespace winrt::ReactNativeCameraCPP::implementation

View File

@ -1,69 +1,67 @@
#pragma once
#include "winrt/Windows.Graphics.Display.h"
#include "CameraRotationHelper.g.h"
// This is a Cpp/WinRT implementation of the Camera Rotation Helper class(C#) on MSDN:
// https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/handle-device-orientation-with-mediacapture#camerarotationhelper-full-code-listing
namespace winrt::ReactNativeCameraCPP::implementation {
struct CameraRotationHelper : CameraRotationHelperT<CameraRotationHelper> {
public:
CameraRotationHelper(winrt::Windows::Devices::Enumeration::EnclosureLocation location);
winrt::event_token OrientationChanged(Windows::Foundation::EventHandler<bool> const &handler);
void OrientationChanged(winrt::event_token const &token) noexcept;
winrt::Windows::Devices::Sensors::SimpleOrientation GetCameraCaptureOrientation();
winrt::Windows::Storage::FileProperties::PhotoOrientation GetConvertedCameraCaptureOrientation();
winrt::Windows::Devices::Sensors::SimpleOrientation GetCameraPreviewOrientation();
int GetCameraPreviewClockwiseDegrees();
private:
bool IsEnclosureLocationExternal(winrt::Windows::Devices::Enumeration::EnclosureLocation enclosureLocation) {
return (
enclosureLocation == nullptr ||
enclosureLocation.Panel() == winrt::Windows::Devices::Enumeration::Panel::Unknown);
}
bool ShouldMirrorPreview();
winrt::Windows::Devices::Sensors::SimpleOrientation GetCameraOrientationRelativeToNativeOrientation();
winrt::Windows::Devices::Sensors::SimpleOrientation SubtractOrientations(
winrt::Windows::Devices::Sensors::SimpleOrientation a,
winrt::Windows::Devices::Sensors::SimpleOrientation b);
winrt::Windows::Devices::Sensors::SimpleOrientation MirrorOrientation(
winrt::Windows::Devices::Sensors::SimpleOrientation orientation);
winrt::Windows::Devices::Sensors::SimpleOrientation AddOrientations(
winrt::Windows::Devices::Sensors::SimpleOrientation a,
winrt::Windows::Devices::Sensors::SimpleOrientation b);
winrt::Windows::Devices::Sensors::SimpleOrientation ConvertDisplayOrientationToSimpleOrientation(
Windows::Graphics::Display::DisplayOrientations orientation);
static winrt::Windows::Storage::FileProperties::PhotoOrientation ConvertSimpleOrientationToPhotoOrientation(
winrt::Windows::Devices::Sensors::SimpleOrientation orientation);
static int ConvertSimpleOrientationToClockwiseDegrees(
winrt::Windows::Devices::Sensors::SimpleOrientation orientation);
static winrt::Windows::Devices::Sensors::SimpleOrientation ConvertClockwiseDegreesToSimpleOrientation(
int orientation);
void SimpleOrientationSensor_OrientationChanged(IInspectable const &sender, IInspectable const &args);
void DisplayInformation_OrientationChanged(IInspectable const &sender, IInspectable const &args);
winrt::Windows::Devices::Sensors::SimpleOrientationSensor::OrientationChanged_revoker
m_sensorOrientationChanged_revoker{};
winrt::Windows::Graphics::Display::DisplayInformation::OrientationChanged_revoker
m_displayOrientationChanged_revoker{};
winrt::Windows::Devices::Enumeration::EnclosureLocation m_cameraEnclosureLocation{nullptr};
winrt::event<Windows::Foundation::EventHandler<bool>> m_orientationChangedEvent;
winrt::Windows::Devices::Sensors::SimpleOrientationSensor m_orientationSensor{
winrt::Windows::Devices::Sensors::SimpleOrientationSensor::GetDefault()};
winrt::Windows::Graphics::Display::DisplayInformation m_displayInformation{
winrt::Windows::Graphics::Display::DisplayInformation::GetForCurrentView()};
};
} // namespace winrt::ReactNativeCameraCPP::implementation
namespace winrt::ReactNativeCameraCPP::factory_implementation {
struct CameraRotationHelper : CameraRotationHelperT<CameraRotationHelper, implementation::CameraRotationHelper> {};
} // namespace winrt::ReactNativeCameraCPP::factory_implementation
#pragma once
#include "CameraRotationHelper.g.h"
// This is a Cpp/WinRT implementation of the Camera Rotation Helper class(C#) on MSDN:
// https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/handle-device-orientation-with-mediacapture#camerarotationhelper-full-code-listing
namespace winrt::ReactNativeCameraCPP::implementation {
struct CameraRotationHelper : CameraRotationHelperT<CameraRotationHelper> {
public:
CameraRotationHelper(winrt::Windows::Devices::Enumeration::EnclosureLocation location);
winrt::event_token OrientationChanged(Windows::Foundation::EventHandler<bool> const &handler);
void OrientationChanged(winrt::event_token const &token) noexcept;
winrt::Windows::Devices::Sensors::SimpleOrientation GetCameraCaptureOrientation();
winrt::Windows::Storage::FileProperties::PhotoOrientation GetConvertedCameraCaptureOrientation();
winrt::Windows::Devices::Sensors::SimpleOrientation GetCameraPreviewOrientation();
int GetCameraPreviewClockwiseDegrees();
private:
bool IsEnclosureLocationExternal(winrt::Windows::Devices::Enumeration::EnclosureLocation enclosureLocation) {
return (
enclosureLocation == nullptr ||
enclosureLocation.Panel() == winrt::Windows::Devices::Enumeration::Panel::Unknown);
}
bool ShouldMirrorPreview();
winrt::Windows::Devices::Sensors::SimpleOrientation GetCameraOrientationRelativeToNativeOrientation();
winrt::Windows::Devices::Sensors::SimpleOrientation SubtractOrientations(
winrt::Windows::Devices::Sensors::SimpleOrientation a,
winrt::Windows::Devices::Sensors::SimpleOrientation b);
winrt::Windows::Devices::Sensors::SimpleOrientation MirrorOrientation(
winrt::Windows::Devices::Sensors::SimpleOrientation orientation);
winrt::Windows::Devices::Sensors::SimpleOrientation AddOrientations(
winrt::Windows::Devices::Sensors::SimpleOrientation a,
winrt::Windows::Devices::Sensors::SimpleOrientation b);
winrt::Windows::Devices::Sensors::SimpleOrientation ConvertDisplayOrientationToSimpleOrientation(
Windows::Graphics::Display::DisplayOrientations orientation);
static winrt::Windows::Storage::FileProperties::PhotoOrientation ConvertSimpleOrientationToPhotoOrientation(
winrt::Windows::Devices::Sensors::SimpleOrientation orientation);
static int ConvertSimpleOrientationToClockwiseDegrees(
winrt::Windows::Devices::Sensors::SimpleOrientation orientation);
static winrt::Windows::Devices::Sensors::SimpleOrientation ConvertClockwiseDegreesToSimpleOrientation(
int orientation);
void SimpleOrientationSensor_OrientationChanged(IInspectable const &sender, IInspectable const &args);
void DisplayInformation_OrientationChanged(IInspectable const &sender, IInspectable const &args);
winrt::Windows::Devices::Sensors::SimpleOrientationSensor::OrientationChanged_revoker
m_sensorOrientationChanged_revoker{};
winrt::Windows::Graphics::Display::DisplayInformation::OrientationChanged_revoker
m_displayOrientationChanged_revoker{};
winrt::Windows::Devices::Enumeration::EnclosureLocation m_cameraEnclosureLocation{nullptr};
winrt::event<Windows::Foundation::EventHandler<bool>> m_orientationChangedEvent;
winrt::Windows::Devices::Sensors::SimpleOrientationSensor m_orientationSensor{
winrt::Windows::Devices::Sensors::SimpleOrientationSensor::GetDefault()};
winrt::Windows::Graphics::Display::DisplayInformation m_displayInformation{
winrt::Windows::Graphics::Display::DisplayInformation::GetForCurrentView()};
};
} // namespace winrt::ReactNativeCameraCPP::implementation
namespace winrt::ReactNativeCameraCPP::factory_implementation {
struct CameraRotationHelper : CameraRotationHelperT<CameraRotationHelper, implementation::CameraRotationHelper> {};
} // namespace winrt::ReactNativeCameraCPP::factory_implementation

View File

@ -2,6 +2,13 @@
#include <functional>
#include <winrt/Windows.Media.Devices.h>
#include <winrt/Windows.Media.MediaProperties.h>
#include "JSValue.h"
#define BarcodeReadEvent L"onBarCodeRead"
namespace winrt::ReactNativeCameraCPP {
class ReactCameraConstants {
public:
@ -36,15 +43,14 @@ class ReactCameraConstants {
static const int CameraWhiteBalanceSunny = (int)winrt::Windows::Media::Devices::ColorTemperaturePreset::Daylight;
static const int CameraWhiteBalanceCloudy = (int)winrt::Windows::Media::Devices::ColorTemperaturePreset::Cloudy;
static const int CameraWhiteBalanceShadow = (int)winrt::Windows::Media::Devices::ColorTemperaturePreset::Candlelight;
static const int CameraWhiteBalanceIncandescent = (int)winrt::Windows::Media::Devices::ColorTemperaturePreset::Tungsten;
static const int CameraWhiteBalanceIncandescent =
(int)winrt::Windows::Media::Devices::ColorTemperaturePreset::Tungsten;
static const int CameraWhiteBalanceFluorescent =
(int)winrt::Windows::Media::Devices::ColorTemperaturePreset::Fluorescent;
static const int CameraVideoQualityAuto =
(int)winrt::Windows::Media::MediaProperties::VideoEncodingQuality::Auto;
static const int CameraVideoQualityAuto = (int)winrt::Windows::Media::MediaProperties::VideoEncodingQuality::Auto;
static const int CameraVideoQuality2160P =
(int)winrt::Windows::Media::MediaProperties::VideoEncodingQuality::Uhd2160p;
static const int CameraVideoQuality1080P =
(int)winrt::Windows::Media::MediaProperties::VideoEncodingQuality::HD1080p;
static const int CameraVideoQuality1080P = (int)winrt::Windows::Media::MediaProperties::VideoEncodingQuality::HD1080p;
static const int CameraVideoQuality720P = (int)winrt::Windows::Media::MediaProperties::VideoEncodingQuality::HD720p;
static const int CameraVideoQualityWVGA = (int)winrt::Windows::Media::MediaProperties::VideoEncodingQuality::Wvga;
static const int CameraVideoQualityVGA = (int)winrt::Windows::Media::MediaProperties::VideoEncodingQuality::Vga;
@ -55,16 +61,35 @@ class ReactCameraConstants {
static const int MediaTypeMP4 = 2;
static const int MediaTypeWMV = 3;
static const int BarcodeReadIntervalMinMS = 200;
static const int BarcodeReadIntervalMS = 500;
static const int BarcodeReadTimeoutMS = 5000;
static winrt::Microsoft::ReactNative::JSValueObject GetAspectConstants() noexcept {
return winrt::Microsoft::ReactNative::JSValueObject{
{"stretch", CameraAspectStretch},
{"fit", CameraAspectFit},
{"fill", CameraAspectFill}
};
{"stretch", CameraAspectStretch}, {"fit", CameraAspectFit}, {"fill", CameraAspectFill}};
}
static winrt::Microsoft::ReactNative::JSValue GetBarcodeConstants() noexcept {
return winrt::Microsoft::ReactNative::JSValue::EmptyObject.Copy();
return winrt::Microsoft::ReactNative::JSValueObject{
{"aztec", "AZTEC"}, // winrt::ZXing::BarcodeType::AZTEC
{"codabar", "CODABAR"}, // winrt::ZXing::BarcodeType::CODABAR
{"code39", "CODE_39"}, // winrt::ZXing::BarcodeType::CODE_39
{"code93", "CODE_93"}, // winrt::ZXing::BarcodeType::CODE_93
{"code128", "CODE_128"}, // winrt::ZXing::BarcodeType::CODE_128
{"datamatrix", "DATA_MATRIX"}, // winrt::ZXing::BarcodeType::DATA_MATRIX
{"ean8", "EAN_8"}, // winrt::ZXing::BarcodeType::EAN_8
{"ean13", "EAN_13"}, // winrt::ZXing::BarcodeType::EAN_13
{"interleaved2of5", "ITF"}, // winrt::ZXing::BarcodeType::ITF
{"maxicode", "MAXICODE"}, // winrt::ZXing::BarcodeType::MAXICODE
{"pdf417", "PDF_417"}, // winrt::ZXing::BarcodeType::PDF_417
{"qr", "QR_CODE"}, // winrt::ZXing::BarcodeType::QR_CODE
{"rss14", "RSS_14"}, // winrt::ZXing::BarcodeType::RSS_14
{"rssexpanded", "RSS_EXPANDED"}, // winrt::ZXing::BarcodeType::RSS_EXPANDED
{"upc_a", "UPC_A"}, // winrt::ZXing::BarcodeType::UPC_A
{"upc_e", "UPC_E"}, // winrt::ZXing::BarcodeType::UPC_E
{"upc_ean", "UPC_EAN_EXTENSION"}, // winrt::ZXing::BarcodeType::UPC_EAN_EXTENSION
};
}
static winrt::Microsoft::ReactNative::JSValueObject GetFaceDetectionConstants() noexcept {
@ -151,4 +176,4 @@ class ReactCameraConstants {
};
}
};
}; // namespace winrt::ReactNativeCameraCPP
}; // namespace winrt::ReactNativeCameraCPP

View File

@ -1,20 +1,12 @@
#pragma once
#include "pch.h"
#include <functional>
#include <sstream>
#include <system_error>
#include <winrt/Windows.Devices.Enumeration.h>
#include <winrt/Windows.Devices.Sensors.h>
#include <winrt/Windows.Media.Mediaproperties.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.UI.Core.h>
#include "JSValue.h"
#include "NativeModules.h"
#include "JSValueTreeWriter.h"
#include "ReactCameraConstants.h"
#include "ReactCameraViewManager.h"
@ -23,7 +15,7 @@ using namespace winrt::Microsoft::ReactNative;
#ifdef RNW61
#define JSVALUEOBJECTPARAMETER
#else
#define JSVALUEOBJECTPARAMETER const&
#define JSVALUEOBJECTPARAMETER const &
#endif
namespace winrt {
@ -89,16 +81,16 @@ struct RNCameraModule {
REACT_METHOD(stopRecording)
void stopRecording(int viewTag) noexcept {
auto asyncOp =
winrt::ReactNativeCameraCPP::implementation::ReactCameraViewManager::StopRecordAsync(viewTag);
auto asyncOp = winrt::ReactNativeCameraCPP::implementation::ReactCameraViewManager::StopRecordAsync(viewTag);
}
REACT_METHOD(isRecording)
void isRecording(int viewTag, winrt::Microsoft::ReactNative::ReactPromise<bool> const &result) noexcept {
auto asyncOp = winrt::ReactNativeCameraCPP::implementation::ReactCameraViewManager::IsRecordingAsync(viewTag, result);
auto asyncOp =
winrt::ReactNativeCameraCPP::implementation::ReactCameraViewManager::IsRecordingAsync(viewTag, result);
asyncOp.Completed(MakeAsyncActionCompletedHandler(result));
}
REACT_METHOD(pausePreview)
void pausePreview(int viewTag) noexcept {
auto asyncOp = winrt::ReactNativeCameraCPP::implementation::ReactCameraViewManager::PausePreviewAsync(viewTag);
@ -128,8 +120,8 @@ struct RNCameraModule {
}
REACT_METHOD(getCameraIds)
void getCameraIds(winrt::Microsoft::ReactNative::ReactPromise<winrt::Microsoft::ReactNative::JSValueArray> const
&result) noexcept {
void getCameraIds(
winrt::Microsoft::ReactNative::ReactPromise<winrt::Microsoft::ReactNative::JSValueArray> const &result) noexcept {
auto asyncOp = winrt::ReactNativeCameraCPP::implementation::ReactCameraViewManager::GetCameraIdsAsync(result);
asyncOp.Completed(MakeAsyncActionCompletedHandler(result));
}

View File

@ -42,7 +42,9 @@ ReactCameraView::~ReactCameraView() {
void ReactCameraView::Initialize() {
m_childElement = winrt::CaptureElement();
Children().Append(m_childElement);
// RNW does not support DropView yet, so we need to manually register to Unloaded event and remove self
// from the static view list
m_unloadedEventToken = Unloaded(winrt::auto_revoke, [ref = get_weak()](auto const &, auto const &) {
@ -80,6 +82,12 @@ void ReactCameraView::UpdateProperties(IJSValueReader const &propertyMapReader)
UpdateAspect(propertyValue.AsInt32());
} else if (propertyName == "defaultVideoQuality") {
UpdateDefaultVideoQuality(propertyValue.AsInt32());
} else if (propertyName == "barCodeScannerEnabled") {
UpdateBarcodeScannerEnabled(propertyValue.AsBoolean());
} else if (propertyName == "barCodeTypes") {
UpdateBarcodeTypes(propertyValue.AsArray());
} else if (propertyName == "barCodeReadIntervalMS") {
UpdateBarcodeReadIntervalMS(propertyValue.AsInt32());
}
}
}
@ -108,14 +116,13 @@ IAsyncAction ReactCameraView::TakePictureAsync(
if (!m_isInitialized) {
capturedPromise.Reject(L"Media device is not initialized.");
return;
co_return;
}
#ifdef RNW61
// Necessary to switch to the UI thread in RNW61
StopBarcodeScanner();
auto dispatcher = Dispatcher();
co_await resume_foreground(dispatcher);
#endif
if (auto mediaCapture = m_childElement.Source()) {
// Default with no options is to save the image to the temp folder and return the uri
@ -168,7 +175,8 @@ IAsyncAction ReactCameraView::TakePictureAsync(
// Add additional metadata to what the camera provided
auto photoOrientation = m_rotationHelper.GetConvertedCameraCaptureOrientation();
auto photoOrientationValue = winrt::BitmapTypedValue(winrt::box_value(photoOrientation), winrt::PropertyType::UInt16);
auto photoOrientationValue =
winrt::BitmapTypedValue(winrt::box_value(photoOrientation), winrt::PropertyType::UInt16);
capturedProperties.Insert(hstring(L"System.Photo.Orientation"), photoOrientationValue);
// Get transform options
@ -228,7 +236,7 @@ IAsyncAction ReactCameraView::TakePictureAsync(
if (writeExif) {
co_await encoder.BitmapProperties().SetPropertiesAsync(capturedProperties);
}
co_await encoder.FlushAsync();
// Get base64-encoded data to return
@ -284,10 +292,9 @@ IAsyncAction ReactCameraView::TakePictureAsync(
capturedPromise.Reject(L"Media device is not initialized.");
}
#ifdef RNW61
// Necessary to switch back to bacground thread in RNW61
co_await resume_background();
#endif
StartBarcodeScanner();
}
IAsyncAction ReactCameraView::RecordAsync(
@ -301,11 +308,10 @@ IAsyncAction ReactCameraView::RecordAsync(
co_return;
}
#ifdef RNW61
// Necessary to switch to the UI thread in RNW61
StopBarcodeScanner();
auto dispatcher = Dispatcher();
co_await resume_foreground(dispatcher);
#endif
if (auto mediaCapture = m_childElement.Source()) {
int quality;
@ -405,10 +411,9 @@ IAsyncAction ReactCameraView::RecordAsync(
capturedPromise.Reject("No media capture device found");
}
#ifdef RNW61
// Necessary to switch back to bacground thread in RNW61
co_await resume_background();
#endif
StartBarcodeScanner();
}
IAsyncAction ReactCameraView::StopRecordAsync() noexcept {
@ -436,12 +441,17 @@ IAsyncAction ReactCameraView::PausePreviewAsync() noexcept {
co_return;
}
auto dispatcher = Dispatcher();
co_await resume_foreground(dispatcher);
if (auto mediaCapture = m_childElement.Source()) {
if (m_isPreview) {
co_await mediaCapture.StopPreviewAsync();
m_isPreview = false;
}
}
co_await resume_background();
}
IAsyncAction ReactCameraView::ResumePreviewAsync() noexcept {
@ -449,12 +459,17 @@ IAsyncAction ReactCameraView::ResumePreviewAsync() noexcept {
co_return;
}
auto dispatcher = Dispatcher();
co_await resume_foreground(dispatcher);
if (auto mediaCapture = m_childElement.Source()) {
if (!m_isPreview) {
co_await mediaCapture.StartPreviewAsync();
m_isPreview = true;
}
}
co_await resume_background();
}
// start a timer to end the recording after the specified time
@ -475,10 +490,12 @@ IAsyncAction ReactCameraView::WaitAndStopRecording() {
// Switch to UI thread to stop recording
auto dispatcher = Dispatcher();
co_await resume_foreground(dispatcher);
co_await m_mediaRecording.StopAsync();
// Reset stream to default
co_await UpdateMediaStreamPropertiesAsync();
co_await resume_background();
}
@ -558,7 +575,7 @@ void ReactCameraView::UpdateWhiteBalance(int whiteBalance) {
void ReactCameraView::UpdateMirrorVideo(bool mirrorVideo) {
m_mirrorVideo = mirrorVideo;
m_childElement.FlowDirection(mirrorVideo ? winrt::FlowDirection::RightToLeft :winrt::FlowDirection::LeftToRight);
m_childElement.FlowDirection(mirrorVideo ? winrt::FlowDirection::RightToLeft : winrt::FlowDirection::LeftToRight);
}
void ReactCameraView::UpdateAspect(int aspect) {
@ -585,6 +602,62 @@ void ReactCameraView::UpdateDefaultVideoQuality(int videoQuality) {
}
}
void ReactCameraView::UpdateBarcodeScannerEnabled(bool barcodeScannerEnabled) {
m_barcodeScannerEnabled = barcodeScannerEnabled;
if (m_barcodeScannerEnabled) {
StartBarcodeScanner();
} else {
StopBarcodeScanner();
}
}
void ReactCameraView::UpdateBarcodeTypes(winrt::JSValueArray const &barcodeTypes) {
m_barcodeTypes.clear();
for (size_t i = 0; i < barcodeTypes.size(); i++) {
auto barCodeTypeStr = barcodeTypes[i].AsString();
if (barCodeTypeStr == "AZTEC") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::AZTEC);
} else if (barCodeTypeStr == "CODABAR") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::CODABAR);
} else if (barCodeTypeStr == "CODE_39") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::CODE_39);
} else if (barCodeTypeStr == "CODE_93") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::CODE_93);
} else if (barCodeTypeStr == "CODE_128") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::CODE_128);
} else if (barCodeTypeStr == "DATA_MATRIX") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::DATA_MATRIX);
} else if (barCodeTypeStr == "EAN_8") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::EAN_8);
} else if (barCodeTypeStr == "EAN_13") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::EAN_13);
} else if (barCodeTypeStr == "ITF") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::ITF);
} else if (barCodeTypeStr == "MAXICODE") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::MAXICODE);
} else if (barCodeTypeStr == "PDF_417") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::PDF_417);
} else if (barCodeTypeStr == "QR_CODE") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::QR_CODE);
} else if (barCodeTypeStr == "RSS_14") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::RSS_14);
} else if (barCodeTypeStr == "RSS_EXPANDED") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::RSS_EXPANDED);
} else if (barCodeTypeStr == "UPC_A") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::UPC_A);
} else if (barCodeTypeStr == "UPC_E") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::UPC_E);
} else if (barCodeTypeStr == "UPC_EAN_EXTENSION") {
m_barcodeTypes.push_back(winrt::ZXing::BarcodeType::UPC_EAN_EXTENSION);
}
}
}
void ReactCameraView::UpdateBarcodeReadIntervalMS(int barcodeReadIntervalMS) {
m_barcodeReadIntervalMS = std::max<int>(ReactCameraConstants::BarcodeReadIntervalMinMS, barcodeReadIntervalMS);
}
// Intialization takes care few things below:
// 1. Register rotation helper to update preview if rotation changes.
// 2. Takes care connected standby scenarios to cleanup and reintialize when suspend/resume
@ -610,6 +683,7 @@ IAsyncAction ReactCameraView::InitializeAsync() {
UpdateWhiteBalance(m_whiteBalance);
UpdateKeepAwake(m_keepAwake);
UpdateMirrorVideo(m_mirrorVideo);
UpdateBarcodeScannerEnabled(m_barcodeScannerEnabled);
co_await mediaCapture.StartPreviewAsync();
m_isPreview = true;
@ -662,7 +736,8 @@ IAsyncAction ReactCameraView::UpdateMediaStreamPropertiesAsync(int videoQuality)
if (auto videoEncodingProperties = mediaEncodingProperties.try_as<winrt::VideoEncodingProperties>()) {
auto resolution = videoEncodingProperties.Width() * videoEncodingProperties.Height();
auto frameRate = videoEncodingProperties.FrameRate().Denominator() > 0
? videoEncodingProperties.FrameRate().Numerator() / videoEncodingProperties.FrameRate().Denominator() : 0;
? videoEncodingProperties.FrameRate().Numerator() / videoEncodingProperties.FrameRate().Denominator()
: 0;
// Save the best encoding for later, in case the target cannot be found
if (bestProperties == nullptr || (resolution >= bestResolution && frameRate >= bestFrameRate)) {
@ -671,17 +746,16 @@ IAsyncAction ReactCameraView::UpdateMediaStreamPropertiesAsync(int videoQuality)
bestFrameRate = frameRate;
}
bool resolutionMatch =
(videoQuality == ReactCameraConstants::CameraVideoQuality2160P &&
bool resolutionMatch = (videoQuality == ReactCameraConstants::CameraVideoQuality2160P &&
videoEncodingProperties.Width() == 3840 && videoEncodingProperties.Height() == 2160) ||
(videoQuality == ReactCameraConstants::CameraVideoQuality1080P &&
videoEncodingProperties.Width() == 1920 && videoEncodingProperties.Height() == 1080) ||
(videoQuality == ReactCameraConstants::CameraVideoQuality720P &&
videoEncodingProperties.Width() == 1280 && videoEncodingProperties.Height() == 720) ||
(videoQuality == ReactCameraConstants::CameraVideoQualityWVGA &&
videoEncodingProperties.Width() == 800 && videoEncodingProperties.Height() == 480) ||
(videoQuality == ReactCameraConstants::CameraVideoQualityVGA &&
videoEncodingProperties.Width() == 640 && videoEncodingProperties.Height() == 480);
(videoQuality == ReactCameraConstants::CameraVideoQuality1080P && videoEncodingProperties.Width() == 1920 &&
videoEncodingProperties.Height() == 1080) ||
(videoQuality == ReactCameraConstants::CameraVideoQuality720P && videoEncodingProperties.Width() == 1280 &&
videoEncodingProperties.Height() == 720) ||
(videoQuality == ReactCameraConstants::CameraVideoQualityWVGA && videoEncodingProperties.Width() == 800 &&
videoEncodingProperties.Height() == 480) ||
(videoQuality == ReactCameraConstants::CameraVideoQualityVGA && videoEncodingProperties.Width() == 640 &&
videoEncodingProperties.Height() == 480);
// Save this encoding if it:
// 1. Has the correct resolution AND
@ -700,9 +774,9 @@ IAsyncAction ReactCameraView::UpdateMediaStreamPropertiesAsync(int videoQuality)
}
if (foundProperties) {
co_await mediaCapture.VideoDeviceController().SetMediaStreamPropertiesAsync(winrt::MediaStreamType::VideoPreview, foundProperties);
co_await mediaCapture.VideoDeviceController().SetMediaStreamPropertiesAsync(
winrt::MediaStreamType::VideoPreview, foundProperties);
}
}
co_return;
}
@ -711,6 +785,7 @@ IAsyncAction ReactCameraView::CleanupMediaCaptureAsync() {
if (m_isInitialized) {
SetEvent(m_signal.get()); // In case recording is still going on
if (auto mediaCapture = m_childElement.Source()) {
StopBarcodeScanner();
if (m_isPreview) {
co_await mediaCapture.StopPreviewAsync();
@ -748,8 +823,7 @@ IAsyncOperation<winrt::DeviceInformation> ReactCameraView::FindCameraDeviceAsync
if (targetDevice == nullptr) {
for (auto cameraDeviceInfo : allVideoDevices) {
if (cameraDeviceInfo.IsEnabled()) {
if (
cameraDeviceInfo.EnclosureLocation() != nullptr &&
if (cameraDeviceInfo.EnclosureLocation() != nullptr &&
cameraDeviceInfo.EnclosureLocation().Panel() == m_panelType) {
// Device matches the panel requested (front/back/etc), take it
targetDevice = cameraDeviceInfo;
@ -778,6 +852,77 @@ IAsyncOperation<winrt::DeviceInformation> ReactCameraView::FindCameraDeviceAsync
co_return targetDevice;
}
void ReactCameraView::StartBarcodeScanner() {
if (m_barcodeScannerEnabled && !m_barcodeScanTimer) {
m_barcodeScanTimer = winrt::Windows::System::Threading::ThreadPoolTimer::CreatePeriodicTimer(
[ref = this->get_strong()](const winrt::Windows::System::Threading::ThreadPoolTimer) noexcept {
auto asyncOp = ref->ScanForBarcodeAsync();
asyncOp.wait_for(std::chrono::milliseconds(ReactCameraConstants::BarcodeReadTimeoutMS));
},
std::chrono::milliseconds(m_barcodeReadIntervalMS));
}
}
void ReactCameraView::StopBarcodeScanner() {
if (m_barcodeScanTimer) {
m_barcodeScanTimer.Cancel();
m_barcodeScanTimer = nullptr;
}
}
winrt::Windows::Foundation::IAsyncAction ReactCameraView::ScanForBarcodeAsync() {
if (!m_isInitialized || !m_barcodeScannerEnabled || !m_isPreview) {
co_return;
}
StopBarcodeScanner();
auto dispatcher = Dispatcher();
co_await resume_foreground(dispatcher);
try {
if (auto mediaCapture = m_childElement.Source()) {
// Capture the image
auto lowLagCapture = co_await mediaCapture.PrepareLowLagPhotoCaptureAsync(
winrt::ImageEncodingProperties().CreateUncompressed(winrt::MediaPixelFormat::Bgra8));
auto capturedPhoto = co_await lowLagCapture.CaptureAsync();
auto softwareBitmap = capturedPhoto.Frame().SoftwareBitmap();
co_await lowLagCapture.FinishAsync();
if (softwareBitmap) {
// Try to read barcode
winrt::array_view<winrt::ZXing::BarcodeType const> barcodeTypes{m_barcodeTypes};
auto barcodeReader = barcodeTypes.size() > 0 ? winrt::ZXing::BarcodeReader(true, true, barcodeTypes)
: winrt::ZXing::BarcodeReader(true, true);
auto barcodeResult = barcodeReader.Read(softwareBitmap, 0, 0);
auto control = this->get_strong().try_as<winrt::FrameworkElement>();
if (barcodeResult && m_reactContext && control) {
m_reactContext.DispatchEvent(
control,
BarcodeReadEvent,
[barcodeResult](winrt::Microsoft::ReactNative::IJSValueWriter const &eventDataWriter) noexcept {
auto result = winrt::JSValueObject();
result["data"] = winrt::to_string(barcodeResult.Text());
result["type"] = winrt::to_string(barcodeResult.Format());
result.WriteTo(eventDataWriter);
});
}
}
}
} catch (...) {
// We can't do anything since this is running in it's own thread,
// there's no way to report the exception, and we want the code to cleanup here
}
co_await resume_background();
StartBarcodeScanner();
}
// update preview if display orientation changes.
void ReactCameraView::OnOrientationChanged(const bool updatePreview) {
if (updatePreview) {
@ -838,7 +983,7 @@ IAsyncOperation<winrt::StorageFile> ReactCameraView::GetOutputStorageFileAsync(i
ext = ".wmv";
break;
}
auto now = winrt::clock::now();
auto ttnow = winrt::clock::to_time_t(now);
struct tm time;
@ -878,7 +1023,7 @@ void ReactCameraView::SetContext(winrt::Microsoft::ReactNative::IReactContext co
m_reactContext = reactContext;
}
winrt::JSValueObject ReactCameraView::GetExifObject(winrt::BitmapPropertySet const& properties) noexcept {
winrt::JSValueObject ReactCameraView::GetExifObject(winrt::BitmapPropertySet const &properties) noexcept {
winrt::JSValueObject exifObject;
for (auto it : properties) {

View File

@ -1,10 +1,9 @@
#pragma once
#include <pch.h>
#include "JSValue.h"
#include "NativeModules.h"
#include "CameraRotationHelper.h"
#include "JSValueTreeWriter.h"
#include "ReactCameraConstants.h"
namespace winrt::ReactNativeCameraCPP {
@ -39,6 +38,9 @@ struct ReactCameraView : winrt::Windows::UI::Xaml::Controls::GridT<ReactCameraVi
void UpdateMirrorVideo(bool mirrorVideo);
void UpdateAspect(int aspect);
void UpdateDefaultVideoQuality(int videoQuality);
void UpdateBarcodeScannerEnabled(bool barcodeScannerEnabled);
void UpdateBarcodeTypes(winrt::Microsoft::ReactNative::JSValueArray const &barcodeTypes);
void UpdateBarcodeReadIntervalMS(int barcodeReadIntervalMS);
fire_and_forget UpdateDeviceId(std::string cameraId);
fire_and_forget UpdateDeviceType(int type);
@ -63,6 +65,10 @@ struct ReactCameraView : winrt::Windows::UI::Xaml::Controls::GridT<ReactCameraVi
winrt::Windows::Storage::StorageFile storageFile,
winrt::Microsoft::ReactNative::JSValueObject const &options);
void StartBarcodeScanner();
void StopBarcodeScanner();
winrt::Windows::Foundation::IAsyncAction ScanForBarcodeAsync();
void OnOrientationChanged(const bool updatePreview);
void OnApplicationSuspending();
void OnApplicationResuming();
@ -98,6 +104,7 @@ struct ReactCameraView : winrt::Windows::UI::Xaml::Controls::GridT<ReactCameraVi
winrt::Windows::System::Display::DisplayRequest m_displayRequest{nullptr};
winrt::Windows::System::Threading::ThreadPoolTimer m_recordTimer{nullptr};
winrt::Windows::System::Threading::ThreadPoolTimer m_barcodeScanTimer{nullptr};
winrt::event_token m_rotationEventToken{};
winrt::Windows::UI::Xaml::Application::Suspending_revoker m_applicationSuspendingEventToken;
@ -112,6 +119,9 @@ struct ReactCameraView : winrt::Windows::UI::Xaml::Controls::GridT<ReactCameraVi
int m_focusMode{ReactCameraConstants::CameraAutoFocusOn};
bool m_isPreview{false};
bool m_mirrorVideo{false};
bool m_barcodeScannerEnabled{false};
int m_barcodeReadIntervalMS{ReactCameraConstants::BarcodeReadIntervalMS};
std::string m_cameraId;
@ -120,7 +130,8 @@ struct ReactCameraView : winrt::Windows::UI::Xaml::Controls::GridT<ReactCameraVi
winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Media::MediaProperties::IMediaEncodingProperties>
m_availableVideoEncodingProperties;
int m_defaultVideoQuality{ReactCameraConstants::CameraVideoQualityAuto};
std::vector<winrt::ZXing::BarcodeType> m_barcodeTypes;
int m_defaultVideoQuality{ReactCameraConstants::CameraVideoQualityAuto};
};
} // namespace winrt::ReactNativeCameraCPP

View File

@ -1,6 +1,7 @@
#include "pch.h"
#include "ReactCameraViewManager.h"
#include "ReactCameraConstants.h"
#include "ReactCameraViewManager.h"
#include <iomanip>
@ -59,8 +60,9 @@ IMapView<hstring, ViewManagerPropertyType> ReactCameraViewManager::NativeProps()
nativeProps.Insert(L"whiteBalance", ViewManagerPropertyType::Number);
nativeProps.Insert(L"torchMode", ViewManagerPropertyType::Number);
nativeProps.Insert(L"flashMode", ViewManagerPropertyType::Number);
// nativeProps.Insert(L"barcodeScannerEnabled", ViewManagerPropertyType::Boolean);
// nativeProps.Insert(L"barCodeTypes", ViewManagerPropertyType::Array);
nativeProps.Insert(L"barCodeScannerEnabled", ViewManagerPropertyType::Boolean);
nativeProps.Insert(L"barCodeTypes", ViewManagerPropertyType::Array);
nativeProps.Insert(L"barCodeReadIntervalMS", ViewManagerPropertyType::Number);
nativeProps.Insert(L"keepAwake", ViewManagerPropertyType::Boolean);
nativeProps.Insert(L"mirrorVideo", ViewManagerPropertyType::Boolean);
nativeProps.Insert(L"defaultVideoQuality", ViewManagerPropertyType::Number);
@ -76,6 +78,20 @@ void ReactCameraViewManager::UpdateProperties(
}
}
// IViewManagerWithExportedEventTypeConstants
ConstantProviderDelegate ReactCameraViewManager::ExportedCustomBubblingEventTypeConstants() noexcept {
return nullptr;
}
ConstantProviderDelegate ReactCameraViewManager::ExportedCustomDirectEventTypeConstants() noexcept {
return [](winrt::Microsoft::ReactNative::IJSValueWriter const &constantWriter) {
constantWriter.WritePropertyName(BarcodeReadEvent);
constantWriter.WriteObjectBegin();
WriteProperty(constantWriter, L"registrationName", BarcodeReadEvent);
constantWriter.WriteObjectEnd();
};
}
void ReactCameraViewManager::RemoveViewFromList(winrt::com_ptr<ReactNativeCameraCPP::ReactCameraView> view) {
auto it = std::find(m_cameraViewInstances.begin(), m_cameraViewInstances.end(), view);
if (it != m_cameraViewInstances.end())
@ -124,7 +140,7 @@ IAsyncAction ReactCameraViewManager::StopRecordAsync(int viewTag) noexcept {
IAsyncAction ReactCameraViewManager::IsRecordingAsync(
int viewTag,
winrt::Microsoft::ReactNative::ReactPromise<bool> const& result) noexcept {
winrt::Microsoft::ReactNative::ReactPromise<bool> const &result) noexcept {
auto capturedPromise = result;
auto index = co_await FindCamera(viewTag);
@ -173,7 +189,7 @@ IAsyncAction ReactCameraViewManager::CheckMediaCapturePermissionAsync(
}
winrt::IAsyncAction ReactCameraViewManager::GetCameraIdsAsync(
winrt::ReactPromise<winrt::JSValueArray> const& result) noexcept {
winrt::ReactPromise<winrt::JSValueArray> const &result) noexcept {
auto capturedPromise = result;
auto allVideoDevices = co_await winrt::DeviceInformation::FindAllAsync(winrt::DeviceClass::VideoCapture);
@ -211,7 +227,7 @@ IAsyncOperation<int> ReactCameraViewManager::FindCamera(int viewTag) noexcept {
co_await resume_background();
index++;
}
co_return - 1;
co_return -1;
}
} // namespace winrt::ReactNativeCameraCPP::implementation

View File

@ -1,5 +1,8 @@
#pragma once
#include "pch.h"
#include "NativeModules.h"
#include "ReactCameraView.h"
namespace winrt::ReactNativeCameraCPP::implementation {
@ -7,7 +10,8 @@ struct ReactCameraViewManager : winrt::implements<
ReactCameraViewManager,
winrt::Microsoft::ReactNative::IViewManager,
winrt::Microsoft::ReactNative::IViewManagerWithReactContext,
winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties> {
winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties,
winrt::Microsoft::ReactNative::IViewManagerWithExportedEventTypeConstants> {
public:
ReactCameraViewManager();
@ -28,6 +32,11 @@ struct ReactCameraViewManager : winrt::implements<
winrt::Windows::UI::Xaml::FrameworkElement const &view,
winrt::Microsoft::ReactNative::IJSValueReader const &propertyMapReader) noexcept;
// IViewManagerWithExportedEventTypeConstants
winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomBubblingEventTypeConstants() noexcept;
winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomDirectEventTypeConstants() noexcept;
static winrt::Windows::Foundation::IAsyncAction TakePictureAsync(
winrt::Microsoft::ReactNative::JSValueObject const &options,
int viewTag,

View File

@ -104,6 +104,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
@ -164,6 +165,7 @@
</Target>
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="$(SolutionDir)\packages\huycn.zxingcpp.winrt.1.0.7\build\native\ZXingWinRT.targets" Condition="Exists('$(SolutionDir)\packages\huycn.zxingcpp.winrt.1.0.7\build\native\ZXingWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
@ -171,5 +173,6 @@
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('$(SolutionDir)\packages\huycn.zxingcpp.winrt.1.0.7\build\native\ZXingWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\huycn.zxingcpp.winrt.1.0.7\build\native\ZXingWinRT.targets'))" />
</Target>
</Project>
</Project>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200316.3" targetFramework="native" />
<package id="huycn.zxingcpp.winrt" version="1.0.7" targetFramework="native" />
</packages>

View File

@ -5,11 +5,11 @@
#include <winrt/Windows.Devices.Sensors.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Graphics.Display.h>
#include <winrt/Windows.Graphics.Imaging.h>
#include <winrt/Windows.Media.Capture.h>
#include <winrt/Windows.Media.Devices.h>
#include <winrt/Windows.Media.MediaProperties.h>
#include <winrt/Windows.Media.Mediaproperties.h>
#include <winrt/Windows.Security.Cryptography.h>
#include <winrt/Windows.Storage.FileProperties.h>
#include <winrt/Windows.Storage.Streams.h>
@ -27,5 +27,4 @@
#include "winrt/Microsoft.ReactNative.h"
#include "JSValueTreeWriter.h"
#include "ReactCameraView.h"
#include "winrt/ZXing.h"

View File

@ -1,166 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
<MinimalCoreWin>true</MinimalCoreWin>
<ProjectGuid>{5898d41d-92cc-48d0-95cd-9954572c266d}</ProjectGuid>
<ProjectName>ReactNativeCameraCPP61</ProjectName>
<RootNamespace>ReactNativeCameraCPP</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.15063.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="ReactNativeWindowsProps">
<ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
<Import Project="$(ReactNativeWindowsDir)\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems" Label="Shared" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="PropertySheet.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
<WarningLevel>Level4</WarningLevel>
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
<!--Temporarily disable cppwinrt heap enforcement to work around xaml compiler generated std::shared_ptr use -->
<AdditionalOptions Condition="'$(CppWinRTHeapEnforcement)'==''">/DWINRT_NO_MAKE_DETECTION %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
<PreprocessorDefinitions>_WINRT_DLL;RNW61;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
<ModuleDefinitionFile>ReactNativeCameraCPP.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\ReactNativeCameraCPP\ReactCameraConstants.h" />
<ClInclude Include="..\ReactNativeCameraCPP\ReactCameraView.h" />
<ClInclude Include="..\ReactNativeCameraCPP\ReactCameraViewManager.h" />
<ClInclude Include="..\ReactNativeCameraCPP\pch.h" />
<ClInclude Include="..\ReactNativeCameraCPP\ReactPackageProvider.h">
<DependentUpon>..\ReactNativeCameraCPP\ReactPackageProvider.idl</DependentUpon>
</ClInclude>
<ClInclude Include="..\ReactNativeCameraCPP\CameraRotationHelper.h">
<DependentUpon>..\ReactNativeCameraCPP\CameraRotationHelper.idl</DependentUpon>
</ClInclude>
<ClInclude Include="..\ReactNativeCameraCPP\ReactCameraModule.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\ReactNativeCameraCPP\ReactCameraView.cpp" />
<ClCompile Include="..\ReactNativeCameraCPP\ReactCameraViewManager.cpp" />
<ClCompile Include="..\ReactNativeCameraCPP\pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\ReactNativeCameraCPP\ReactPackageProvider.cpp">
<DependentUpon>..\ReactNativeCameraCPP\ReactPackageProvider.idl</DependentUpon>
</ClCompile>
<ClCompile Include="..\ReactNativeCameraCPP\CameraRotationHelper.cpp">
<DependentUpon>..\ReactNativeCameraCPP\CameraRotationHelper.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<ItemGroup>
<Midl Include="..\ReactNativeCameraCPP\ReactPackageProvider.idl" />
</ItemGroup>
<ItemGroup>
<Midl Include="..\ReactNativeCameraCPP\CameraRotationHelper.idl" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="..\ReactNativeCameraCPP\ReactNativeCameraCPP.def" />
</ItemGroup>
<ItemGroup>
<None Include="PropertySheet.props" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(ReactNativeWindowsDir)\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj">
<Project>{f7d32bd0-2749-483e-9a0d-1635ef7e3136}</Project>
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
<MinimalCoreWin>true</MinimalCoreWin>
<ProjectGuid>{5898d41d-92cc-48d0-95cd-9954572c266d}</ProjectGuid>
<ProjectName>ReactNativeCameraCPP61</ProjectName>
<RootNamespace>ReactNativeCameraCPP</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.15063.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="ReactNativeWindowsProps">
<ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
<Import Project="$(ReactNativeWindowsDir)\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems" Label="Shared" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="PropertySheet.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
<WarningLevel>Level4</WarningLevel>
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
<!--Temporarily disable cppwinrt heap enforcement to work around xaml compiler generated std::shared_ptr use -->
<AdditionalOptions Condition="'$(CppWinRTHeapEnforcement)'==''">/DWINRT_NO_MAKE_DETECTION %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
<PreprocessorDefinitions>_WINRT_DLL;RNW61;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
<ModuleDefinitionFile>..\ReactNativeCameraCPP\ReactNativeCameraCPP.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\ReactNativeCameraCPP\ReactCameraConstants.h" />
<ClInclude Include="..\ReactNativeCameraCPP\ReactCameraView.h" />
<ClInclude Include="..\ReactNativeCameraCPP\ReactCameraViewManager.h" />
<ClInclude Include="..\ReactNativeCameraCPP\pch.h" />
<ClInclude Include="..\ReactNativeCameraCPP\ReactPackageProvider.h">
<DependentUpon>..\ReactNativeCameraCPP\ReactPackageProvider.idl</DependentUpon>
</ClInclude>
<ClInclude Include="..\ReactNativeCameraCPP\CameraRotationHelper.h">
<DependentUpon>..\ReactNativeCameraCPP\CameraRotationHelper.idl</DependentUpon>
</ClInclude>
<ClInclude Include="..\ReactNativeCameraCPP\ReactCameraModule.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\ReactNativeCameraCPP\ReactCameraView.cpp" />
<ClCompile Include="..\ReactNativeCameraCPP\ReactCameraViewManager.cpp" />
<ClCompile Include="..\ReactNativeCameraCPP\pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\ReactNativeCameraCPP\ReactPackageProvider.cpp">
<DependentUpon>..\ReactNativeCameraCPP\ReactPackageProvider.idl</DependentUpon>
</ClCompile>
<ClCompile Include="..\ReactNativeCameraCPP\CameraRotationHelper.cpp">
<DependentUpon>..\ReactNativeCameraCPP\CameraRotationHelper.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<ItemGroup>
<Midl Include="..\ReactNativeCameraCPP\ReactPackageProvider.idl" />
</ItemGroup>
<ItemGroup>
<Midl Include="..\ReactNativeCameraCPP\CameraRotationHelper.idl" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="..\ReactNativeCameraCPP\ReactNativeCameraCPP.def" />
</ItemGroup>
<ItemGroup>
<None Include="PropertySheet.props" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(ReactNativeWindowsDir)\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj">
<Project>{f7d32bd0-2749-483e-9a0d-1635ef7e3136}</Project>
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="$(SolutionDir)\packages\huycn.zxingcpp.winrt.1.0.7\build\native\ZXingWinRT.targets" Condition="Exists('$(SolutionDir)\packages\huycn.zxingcpp.winrt.1.0.7\build\native\ZXingWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('$(SolutionDir)\packages\huycn.zxingcpp.winrt.1.0.7\build\native\ZXingWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\huycn.zxingcpp.winrt.1.0.7\build\native\ZXingWinRT.targets'))" />
</Target>
</Project>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
<package id="huycn.zxingcpp.winrt" version="1.0.7" targetFramework="native" />
</packages>