android/camera: Implement image flipping
We use libyuv's Mirror function to handle horizontal flip. Regarding the vertical flip, libyuv doc states that 'just set a negative height'
This commit is contained in:
parent
9f1114aace
commit
1796965504
@ -210,8 +210,13 @@ CaptureSession::CaptureSession(ACameraManager* manager, const std::string& id) {
|
||||
#undef CAMERA_CALL
|
||||
#undef CREATE
|
||||
|
||||
Interface::Interface(Factory& factory_, const std::string& id_, const Service::CAM::Flip& flip_)
|
||||
: factory(factory_), id(id_), flip(flip_) {}
|
||||
Interface::Interface(Factory& factory_, const std::string& id_, const Service::CAM::Flip& flip)
|
||||
: factory(factory_), id(id_) {
|
||||
mirror = base_mirror =
|
||||
flip == Service::CAM::Flip::Horizontal || flip == Service::CAM::Flip::Reverse;
|
||||
invert = base_invert =
|
||||
flip == Service::CAM::Flip::Vertical || flip == Service::CAM::Flip::Reverse;
|
||||
}
|
||||
|
||||
Interface::~Interface() = default;
|
||||
|
||||
@ -227,8 +232,11 @@ void Interface::SetResolution(const Service::CAM::Resolution& resolution_) {
|
||||
resolution = resolution_;
|
||||
}
|
||||
|
||||
void Interface::SetFlip(Service::CAM::Flip flip_) {
|
||||
flip = flip_;
|
||||
void Interface::SetFlip(Service::CAM::Flip flip) {
|
||||
mirror = base_mirror ^
|
||||
(flip == Service::CAM::Flip::Horizontal || flip == Service::CAM::Flip::Reverse);
|
||||
invert =
|
||||
base_invert ^ (flip == Service::CAM::Flip::Vertical || flip == Service::CAM::Flip::Reverse);
|
||||
}
|
||||
|
||||
void Interface::SetFormat(Service::CAM::OutputFormat format_) {
|
||||
@ -265,19 +273,32 @@ std::vector<u16> Interface::ReceiveFrame() {
|
||||
scaled_y.data(), resolution.width, scaled_u.data(), resolution.width / 4,
|
||||
scaled_v.data(), resolution.width / 4, resolution.width, resolution.height,
|
||||
libyuv::kFilterBilinear);
|
||||
// TODO: Record and apply flip
|
||||
|
||||
if (mirror) {
|
||||
std::vector<u8> mirrored_y(scaled_y.size());
|
||||
std::vector<u8> mirrored_u(scaled_u.size());
|
||||
std::vector<u8> mirrored_v(scaled_v.size());
|
||||
libyuv::I420Mirror(scaled_y.data(), resolution.width, scaled_u.data(), resolution.width / 4,
|
||||
scaled_v.data(), resolution.width / 4, mirrored_y.data(),
|
||||
resolution.width, mirrored_u.data(), resolution.width / 4,
|
||||
mirrored_v.data(), resolution.width / 4, resolution.width,
|
||||
resolution.height);
|
||||
scaled_y.swap(mirrored_y);
|
||||
scaled_u.swap(mirrored_u);
|
||||
scaled_v.swap(mirrored_v);
|
||||
}
|
||||
|
||||
std::vector<u16> output(resolution.width * resolution.height);
|
||||
if (format == Service::CAM::OutputFormat::RGB565) {
|
||||
libyuv::I420ToRGB565(scaled_y.data(), resolution.width, scaled_u.data(),
|
||||
resolution.width / 4, scaled_v.data(), resolution.width / 4,
|
||||
reinterpret_cast<u8*>(output.data()), resolution.width * 2,
|
||||
resolution.width, resolution.height);
|
||||
resolution.width, invert ? -resolution.height : resolution.height);
|
||||
} else {
|
||||
libyuv::I420ToYUY2(scaled_y.data(), resolution.width, scaled_u.data(), resolution.width / 4,
|
||||
scaled_v.data(), resolution.width / 4,
|
||||
reinterpret_cast<u8*>(output.data()), resolution.width * 2,
|
||||
resolution.width, resolution.height);
|
||||
resolution.width, invert ? -resolution.height : resolution.height);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
@ -37,7 +37,13 @@ private:
|
||||
std::string id;
|
||||
|
||||
Service::CAM::Resolution resolution;
|
||||
Service::CAM::Flip flip;
|
||||
|
||||
// Flipping parameters. mirror = horizontal, invert = vertical.
|
||||
bool base_mirror{};
|
||||
bool base_invert{};
|
||||
bool mirror{};
|
||||
bool invert{};
|
||||
|
||||
Service::CAM::OutputFormat format;
|
||||
// std::vector<u16> image; // Data fetched from the frontend
|
||||
// bool opened{}; // Whether the camera was successfully opened
|
||||
|
@ -29,7 +29,12 @@ void CleanupJNI(JNIEnv* env) {
|
||||
env->DeleteGlobalRef(s_still_image_camera_helper_class);
|
||||
}
|
||||
|
||||
Interface::Interface(jstring path_, const Service::CAM::Flip& flip_) : path(path_), flip(flip_) {}
|
||||
Interface::Interface(jstring path_, const Service::CAM::Flip& flip) : path(path_) {
|
||||
mirror = base_mirror =
|
||||
flip == Service::CAM::Flip::Horizontal || flip == Service::CAM::Flip::Reverse;
|
||||
invert = base_invert =
|
||||
flip == Service::CAM::Flip::Vertical || flip == Service::CAM::Flip::Reverse;
|
||||
}
|
||||
|
||||
Interface::~Interface() {
|
||||
Factory::last_path = nullptr;
|
||||
@ -70,13 +75,20 @@ void Interface::StartCapture() {
|
||||
info.width, info.height);
|
||||
BITMAP_CALL(unlockPixels(env, bitmap));
|
||||
|
||||
if (mirror) {
|
||||
std::vector<u8> mirrored(data.size());
|
||||
libyuv::ARGBMirror(data.data(), info.stride, mirrored.data(), info.stride, info.width,
|
||||
info.height);
|
||||
data.swap(mirrored);
|
||||
}
|
||||
|
||||
image.resize(info.height * info.width);
|
||||
if (format == Service::CAM::OutputFormat::RGB565) {
|
||||
libyuv::ARGBToRGB565(data.data(), info.stride, reinterpret_cast<u8*>(image.data()),
|
||||
info.width * 2, info.width, info.height);
|
||||
info.width * 2, info.width, invert ? -info.height : info.height);
|
||||
} else {
|
||||
libyuv::ARGBToYUY2(data.data(), info.stride, reinterpret_cast<u8*>(image.data()),
|
||||
info.width * 2, info.width, info.height);
|
||||
info.width * 2, info.width, invert ? -info.height : info.height);
|
||||
}
|
||||
opened = true;
|
||||
|
||||
@ -87,8 +99,11 @@ void Interface::SetResolution(const Service::CAM::Resolution& resolution_) {
|
||||
resolution = resolution_;
|
||||
}
|
||||
|
||||
void Interface::SetFlip(Service::CAM::Flip flip_) {
|
||||
flip = flip_;
|
||||
void Interface::SetFlip(Service::CAM::Flip flip) {
|
||||
mirror = base_mirror ^
|
||||
(flip == Service::CAM::Flip::Horizontal || flip == Service::CAM::Flip::Reverse);
|
||||
invert =
|
||||
base_invert ^ (flip == Service::CAM::Flip::Vertical || flip == Service::CAM::Flip::Reverse);
|
||||
}
|
||||
|
||||
void Interface::SetFormat(Service::CAM::OutputFormat format_) {
|
||||
|
@ -31,7 +31,13 @@ public:
|
||||
private:
|
||||
jstring path;
|
||||
Service::CAM::Resolution resolution;
|
||||
Service::CAM::Flip flip;
|
||||
|
||||
// Flipping parameters. mirror = horizontal, invert = vertical.
|
||||
bool base_mirror{};
|
||||
bool base_invert{};
|
||||
bool mirror{};
|
||||
bool invert{};
|
||||
|
||||
Service::CAM::OutputFormat format;
|
||||
std::vector<u16> image; // Data fetched from the frontend
|
||||
bool opened{}; // Whether the camera was successfully opened
|
||||
|
Loading…
x
Reference in New Issue
Block a user