Add XmpBuilder
This commit is contained in:
103
openVulkanoCpp/Image/XmpBuilder.cpp
Normal file
103
openVulkanoCpp/Image/XmpBuilder.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "XmpBuilder.hpp"
|
||||||
|
#include "Extensions/FmtFormatter.hpp"
|
||||||
|
|
||||||
|
namespace OpenVulkano::Image
|
||||||
|
{
|
||||||
|
XmpBuilder::XmpBuilder()
|
||||||
|
{
|
||||||
|
xmpData << "<?xpacket begin=\"\xEF\xBB\xBF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n"; // XMP Wrapper
|
||||||
|
xmpData << "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\"><rdf:RDF"
|
||||||
|
" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""
|
||||||
|
" xmlns:crs=\"http://ns.adobe.com/camera-raw-settings/1.0/\""
|
||||||
|
" xmlns:camera=\"http://ns.adobe.com/camera/1.0/\""
|
||||||
|
" xmlns:cineGeo=\"http://ns.adobe.com/cineGeo/1.0/\"" // Cinema/Geometric namespace
|
||||||
|
" xmlns:exif=\"http://ns.adobe.com/exif/1.0/\"" // EXIF namespace
|
||||||
|
" xmlns:aux=\"http://ns.adobe.com/exif/1.0/aux/\"" // Auxiliary EXIF namespace
|
||||||
|
" xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"" // Base XMP namespace
|
||||||
|
" xmlns:photoshop=\"http://ns.adobe.com/photoshop/1.0/\""
|
||||||
|
" xmlns:tiff=\"http://ns.adobe.com/tiff/1.0/\""
|
||||||
|
"><rdf:Description rdf:about=\"\">";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string XmpBuilder::Finalize()
|
||||||
|
{
|
||||||
|
if (!complete)
|
||||||
|
{ // Finalize
|
||||||
|
xmpData << "</rdf:Description></rdf:RDF></x:xmpmeta>";
|
||||||
|
xmpData << "<?xpacket end=\"w\"?>"; // XMP Wrapper
|
||||||
|
complete = true;
|
||||||
|
}
|
||||||
|
return xmpData.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] XmpBuilder& XmpBuilder::SetCameraIntrinsic(const Math::CameraIntrinsicWithResolution& intrinsic)
|
||||||
|
{
|
||||||
|
// Calibration matrix in row-major format
|
||||||
|
const auto& mat = intrinsic.GetMatrix();
|
||||||
|
xmpData << fmt::format("<camera:CalibrationMatrix>{} {} {} {} {} {} {} {} {}</camera:CalibrationMatrix>",
|
||||||
|
mat[0][0], mat[1][0], mat[2][0], mat[0][1], mat[1][1], mat[2][1], mat[0][2], mat[1][2], mat[2][2]);
|
||||||
|
xmpData << fmt::format("<camera:IntrinsicMatrix><rdf:Description>"
|
||||||
|
"<camera:FocalLengthX>{}</camera:FocalLengthX><camera:FocalLengthY>{}</camera:FocalLengthY>"
|
||||||
|
"<camera:PrincipalPointX>{}</camera:PrincipalPointX><camera:PrincipalPointY>{}</camera:PrincipalPointY>"
|
||||||
|
"</rdf:Description></camera:IntrinsicMatrix>",
|
||||||
|
intrinsic.Fx(), intrinsic.Fy(), intrinsic.Cx(), intrinsic.Cy() );
|
||||||
|
// Field of View
|
||||||
|
xmpData << fmt::format("<camera:FieldOfView><rdf:Description>"
|
||||||
|
"<camera:Horizontal>{}</camera:Horizontal><camera:Vertical>{}</camera:Vertical>"
|
||||||
|
"</rdf:Description></camera:FieldOfView>",
|
||||||
|
Math::Utils::degrees(intrinsic.GetFovX()), Math::Utils::degrees(intrinsic.GetFovY()));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] XmpBuilder& XmpBuilder::SetPosition(const Math::Vector3f& position)
|
||||||
|
{
|
||||||
|
xmpData << fmt::format("<cineGeo:Position><rdf:Description>"
|
||||||
|
"<cineGeo:X>{}</cineGeo:X><cineGeo:Y>{}</cineGeo:Y><cineGeo:Z>{}</cineGeo:Z>"
|
||||||
|
"</rdf:Description></cineGeo:Position>",
|
||||||
|
position.x, position.y, position.z);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] XmpBuilder& XmpBuilder::SetOrientation(const Math::Vector3f& orientation)
|
||||||
|
{
|
||||||
|
Math::Vector3f ori = Math::Utils::degrees(orientation);
|
||||||
|
xmpData << fmt::format("<cineGeo:Rotation><rdf:Description>"
|
||||||
|
"<cineGeo:X>{}</cineGeo:X><cineGeo:Y>{}</cineGeo:Y><cineGeo:Z>{}</cineGeo:Z>"
|
||||||
|
"</rdf:Description></cineGeo:Rotation>",
|
||||||
|
ori.x, ori.y, ori.z);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] XmpBuilder& XmpBuilder::SetSensorSize(const Math::Vector2f& sensorSize)
|
||||||
|
{
|
||||||
|
xmpData << fmt::format("<camera:SensorSize><rdf:Description>"
|
||||||
|
"<camera:Width>{}</camera:Width><camera:Height>{}</camera:Height>"
|
||||||
|
"</rdf:Description></camera:SensorSize>",
|
||||||
|
sensorSize.x, sensorSize.y);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] XmpBuilder& XmpBuilder::SetFocalLength(const float focalLengthMM)
|
||||||
|
{
|
||||||
|
xmpData << "<camera:FocalLength>" << focalLengthMM << "</camera:FocalLength>";
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] XmpBuilder& XmpBuilder::SetExposureTime(double exposureTime)
|
||||||
|
{
|
||||||
|
xmpData << fmt::format("<exif:ExposureTime>{0}</exif:ExposureTime><aux:ExposureTime>{0}</aux:ExposureTime>", exposureTime);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] XmpBuilder& XmpBuilder::SetCreateDate(const std::string& createDate)
|
||||||
|
{
|
||||||
|
xmpData << "<xmp:CreateDate>" << createDate << "</xmp:CreateDate>";
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
openVulkanoCpp/Image/XmpBuilder.hpp
Normal file
36
openVulkanoCpp/Image/XmpBuilder.hpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Math/CameraIntrinsic.hpp"
|
||||||
|
#include "Math/Pose.hpp"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace OpenVulkano::Image
|
||||||
|
{
|
||||||
|
class XmpBuilder final
|
||||||
|
{
|
||||||
|
std::stringstream xmpData;
|
||||||
|
bool complete = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
XmpBuilder();
|
||||||
|
|
||||||
|
[[maybe_unused]] XmpBuilder& SetCameraIntrinsic(const Math::CameraIntrinsicWithResolution& intrinsic);
|
||||||
|
[[maybe_unused]] XmpBuilder& SetPose(const Math::PoseF& pose) { SetPosition(pose.GetPosition()); SetOrientation(pose.GetOrientationAsEuler()); return *this; }
|
||||||
|
[[maybe_unused]] XmpBuilder& SetPosition(const Math::Vector3f& position);
|
||||||
|
[[maybe_unused]] XmpBuilder& SetOrientation(const Math::Vector3f& orientation); // in rad
|
||||||
|
[[maybe_unused]] XmpBuilder& SetSensorSize(const Math::Vector2f& sensorSize);
|
||||||
|
|
||||||
|
[[maybe_unused]] XmpBuilder& SetFocalLength(float focalLengthMM);
|
||||||
|
[[maybe_unused]] XmpBuilder& SetExposureTime(double exposureTime);
|
||||||
|
[[maybe_unused]] XmpBuilder& SetCreateDate(const std::string& createDate);
|
||||||
|
|
||||||
|
[[maybe_unused]] std::string Close() { return Finalize(); }
|
||||||
|
std::string Finalize();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -53,6 +53,8 @@ namespace OpenVulkano::Math
|
|||||||
|
|
||||||
[[nodiscard]] Quaternion<T>& GetOrientation() { return m_orientation; }
|
[[nodiscard]] Quaternion<T>& GetOrientation() { return m_orientation; }
|
||||||
|
|
||||||
|
[[nodiscard]] Math::Vector3f GetOrientationAsEuler() const { return Math::Utils::eulerAngles(m_orientation); }
|
||||||
|
|
||||||
void SetOrientation(const Math::Quaternion<T>& orientation) { m_orientation = orientation; }
|
void SetOrientation(const Math::Quaternion<T>& orientation) { m_orientation = orientation; }
|
||||||
|
|
||||||
void SetOrientation(const Math::Vector3_SIMD<T>& eulerAngle) { m_orientation = Math::Utils::qua(eulerAngle); }
|
void SetOrientation(const Math::Vector3_SIMD<T>& eulerAngle) { m_orientation = Math::Utils::qua(eulerAngle); }
|
||||||
|
|||||||
Reference in New Issue
Block a user