99 percent complete
This commit is contained in:
parent
2ea4211c4b
commit
a7317de4e4
6
Makefile
6
Makefile
@ -25,7 +25,7 @@ LINUX_GL_LIBS = -lGL
|
|||||||
|
|
||||||
CXXFLAGS = -std=c++20 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
CXXFLAGS = -std=c++20 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||||
CXXFLAGS += -DIMGUI_DEFINE_MATH_OPERATORS -Ofast
|
CXXFLAGS += -DIMGUI_DEFINE_MATH_OPERATORS -Ofast
|
||||||
LIBS =
|
LIBS = -lexiv2
|
||||||
|
|
||||||
##---------------------------------------------------------------------
|
##---------------------------------------------------------------------
|
||||||
## OPENGL ES
|
## OPENGL ES
|
||||||
@ -44,9 +44,9 @@ LIBS =
|
|||||||
|
|
||||||
ifeq ($(UNAME_S), Linux) #LINUX
|
ifeq ($(UNAME_S), Linux) #LINUX
|
||||||
ECHO_MESSAGE = "Linux"
|
ECHO_MESSAGE = "Linux"
|
||||||
LIBS += $(LINUX_GL_LIBS) -ldl `sdl2-config --libs`
|
LIBS += $(LINUX_GL_LIBS) -ldl -L/usr/lib -lSDL2
|
||||||
|
|
||||||
CXXFLAGS += `sdl2-config --cflags`
|
CXXFLAGS += -I/usr/include/SDL2 -D_REENTRANT
|
||||||
CFLAGS = $(CXXFLAGS)
|
CFLAGS = $(CXXFLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ Collapsed=0
|
|||||||
|
|
||||||
[Window][Main]
|
[Window][Main]
|
||||||
Pos=0,0
|
Pos=0,0
|
||||||
Size=1673,1237
|
Size=1176,1263
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Help]
|
[Window][Help]
|
||||||
@ -22,3 +22,8 @@ Pos=136,255
|
|||||||
Size=177,114
|
Size=177,114
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][EXIF]
|
||||||
|
Pos=36,29
|
||||||
|
Size=276,318
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
310
main.cpp
310
main.cpp
@ -7,6 +7,7 @@
|
|||||||
#include "lib/imgui.h"
|
#include "lib/imgui.h"
|
||||||
#include "lib/imgui_internal.h"
|
#include "lib/imgui_internal.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <exiv2/tags.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -34,50 +35,139 @@
|
|||||||
#include "lib/backends/tex_inspect_opengl.h"
|
#include "lib/backends/tex_inspect_opengl.h"
|
||||||
#include "lib/argparse.hpp"
|
#include "lib/argparse.hpp"
|
||||||
|
|
||||||
|
#include <exiv2/exiv2.hpp>
|
||||||
|
|
||||||
struct Args : public argparse::Args {
|
struct Args : public argparse::Args {
|
||||||
std::string &fpath = arg("path to the image");
|
std::string &fpath = arg("path to the image");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct EXIFData {
|
||||||
|
std::string CameraMake;
|
||||||
|
std::string CameraModel;
|
||||||
|
std::string LensModel;
|
||||||
|
std::string ImageOrientation;
|
||||||
|
std::string ImageDimensionX;
|
||||||
|
std::string ImageDimensiony;
|
||||||
|
std::string ISO;
|
||||||
|
std::string ShutterSpeed;
|
||||||
|
std::string FNumber;
|
||||||
|
std::string FocalLength;
|
||||||
|
std::string ExposureBias;
|
||||||
|
std::string MeteringMode;
|
||||||
|
std::string Flash;
|
||||||
|
std::string Time;
|
||||||
|
std::string TimeTaken;
|
||||||
|
std::string TimeTakenOffset;
|
||||||
|
std::string GPSLat;
|
||||||
|
std::string GPSLatref;
|
||||||
|
std::string GPSLon;
|
||||||
|
std::string GPSLonref;
|
||||||
|
};
|
||||||
|
|
||||||
struct Texture
|
struct Texture
|
||||||
{
|
{
|
||||||
ImTextureID texture;
|
ImTextureID texture;
|
||||||
ImVec2 size;
|
ImVec2 size;
|
||||||
int channels;
|
int channels;
|
||||||
|
EXIFData exif;
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t* image = nullptr;
|
static uint8_t* image = nullptr;
|
||||||
|
|
||||||
Texture LoadTexture(const char * path)
|
|
||||||
{
|
|
||||||
const int channelCount = 4;
|
|
||||||
int imageFileChannelCount;
|
|
||||||
int width, height;
|
|
||||||
image = (uint8_t *)stbi_load(path, &width, &height, &imageFileChannelCount, channelCount);
|
|
||||||
if (image == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s\nFailed to open %s\n", stbi_failure_reason(), path);
|
|
||||||
|
|
||||||
return {nullptr,{0,0}};
|
EXIFData printExifData(const std::string& imagePath) {
|
||||||
|
EXIFData d;
|
||||||
|
d.CameraMake = "NULL";
|
||||||
|
try {
|
||||||
|
// Load the image
|
||||||
|
Exiv2::Image::UniquePtr img = Exiv2::ImageFactory::open(imagePath);
|
||||||
|
if (img.get() == 0) {
|
||||||
|
std::cerr << "Error: Could not open image file " << imagePath << std::endl;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
img->readMetadata();
|
||||||
|
|
||||||
|
// Get the Exif data
|
||||||
|
Exiv2::ExifData &exifData = img->exifData();
|
||||||
|
if (exifData.empty()) {
|
||||||
|
std::cerr << "No EXIF data found in file " << imagePath << std::endl;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to print EXIF data if available
|
||||||
|
auto printExifValue = [&exifData](const char* key, std::string *d) {
|
||||||
|
Exiv2::ExifKey exifKey(key);
|
||||||
|
Exiv2::ExifData::const_iterator pos = exifData.findKey(exifKey);
|
||||||
|
if (pos != exifData.end()) {
|
||||||
|
*d = pos->value().toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Print common EXIF data
|
||||||
|
printExifValue("Exif.Image.Make", &d.CameraMake);
|
||||||
|
printExifValue("Exif.Image.Model", &d.CameraModel);
|
||||||
|
printExifValue("Exif.Photo.LensModel", &d.LensModel);
|
||||||
|
|
||||||
|
printExifValue("Exif.Image.Orientation", &d.ImageOrientation);
|
||||||
|
//
|
||||||
|
printExifValue("Exif.Photo.ExposureTime", &d.ShutterSpeed);
|
||||||
|
printExifValue("Exif.Photo.FNumber", &d.FNumber);
|
||||||
|
printExifValue("Exif.Photo.ISOSpeedRatings", &d.ISO);
|
||||||
|
printExifValue("Exif.Photo.FocalLength", &d.FocalLength);
|
||||||
|
printExifValue("Exif.Photo.ExposureBiasValue", &d.ExposureBias);
|
||||||
|
printExifValue("Exif.Photo.MeteringMode", &d.MeteringMode);
|
||||||
|
printExifValue("Exif.Photo.Flash", &d.Flash);
|
||||||
|
|
||||||
|
printExifValue("Exif.Image.DateTime", &d.Time);
|
||||||
|
printExifValue("Exif.Photo.DateTimeOriginal", &d.TimeTaken);
|
||||||
|
printExifValue("Exif.Photo.OffsetTime", &d.TimeTakenOffset);
|
||||||
|
printExifValue("Exif.Photo.PixelXDimension", &d.ImageDimensionX);
|
||||||
|
printExifValue("Exif.Photo.PixelYDimension", &d.ImageDimensiony);
|
||||||
|
|
||||||
|
printExifValue("Exif.GPSInfo.GPSLatitudeRef", &d.GPSLatref);
|
||||||
|
printExifValue("Exif.GPSInfo.GPSLatitude", &d.GPSLat);
|
||||||
|
printExifValue("Exif.GPSInfo.GPSLongitudeRef", &d.GPSLonref);
|
||||||
|
printExifValue("Exif.GPSInfo.GPSLongitude", &d.GPSLon);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Exif.Image.Make 0x010f Ascii 5 SONY
|
||||||
|
Exif.Image.Model 0x0110 Ascii 10 ILCE-7RM5
|
||||||
|
|
||||||
|
Exif.Image.Orientation 0x0112 Short 1 8
|
||||||
|
Exif.Photo.PixelXDimension 0xa002 Long 1 9504
|
||||||
|
Exif.Photo.PixelYDimension 0xa003 Long 1 6336
|
||||||
|
|
||||||
|
Exif.Photo.ExposureTime 0x829a Rational 1 1/400
|
||||||
|
Exif.Photo.FNumber 0x829d Rational 1 56/10
|
||||||
|
Exif.Photo.ISOSpeedRatings 0x8827 Short 1 100
|
||||||
|
Exif.Photo.FocalLength 0x920a Rational 1 400/10
|
||||||
|
Exif.Photo.ExposureBiasValue 0x9204 SRational 1 -10/10
|
||||||
|
Exif.Photo.MeteringMode 0x9207 Short 1 5
|
||||||
|
Exif.Photo.Flash 0x9209 Short 1 16
|
||||||
|
|
||||||
|
Exif.Image.DateTime 0x0132 Ascii 20 2024:06:07 08:58:07
|
||||||
|
Exif.Photo.DateTimeOriginal 0x9003 Ascii 20 2024:06:07 08:58:07
|
||||||
|
Exif.Photo.OffsetTime 0x9010 Ascii 7 -05:00
|
||||||
|
|
||||||
|
Exif.GPSInfo.GPSLatitudeRef 0x0001 Ascii 2 N
|
||||||
|
Exif.GPSInfo.GPSLatitude 0x0002 Rational 3 40/1 43/1 32231/1000
|
||||||
|
Exif.GPSInfo.GPSLongitudeRef 0x0003 Ascii 2 W
|
||||||
|
Exif.GPSInfo.GPSLongitude 0x0004 Rational 3 73/1 59/1 16688/1000
|
||||||
|
*/
|
||||||
|
|
||||||
|
} catch (Exiv2::Error& e) {
|
||||||
|
std::cerr << "Error: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum dataFormat = GL_RGBA;
|
return d;
|
||||||
GLuint textureHandle;
|
|
||||||
glGenTextures(1, &textureHandle);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textureHandle);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, dataFormat, GL_UNSIGNED_BYTE, image);
|
|
||||||
|
|
||||||
Texture t;
|
|
||||||
t.texture = (void*)(uintptr_t)(textureHandle);
|
|
||||||
t.size = ImVec2((float)width,(float)height);
|
|
||||||
t.channels = channelCount;
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture ReloadTexture(ImTextureID id, int width, int height) {
|
|
||||||
GLuint tid = (GLuint)(uintptr_t)id;
|
|
||||||
|
Texture ReloadTexture(Texture tin, int width, int height) {
|
||||||
|
GLuint tid = (GLuint)(uintptr_t)tin.texture;
|
||||||
glDeleteTextures((GLsizei)1, &tid);
|
glDeleteTextures((GLsizei)1, &tid);
|
||||||
|
|
||||||
GLenum dataFormat = GL_RGBA;
|
GLenum dataFormat = GL_RGBA;
|
||||||
@ -91,6 +181,8 @@ Texture ReloadTexture(ImTextureID id, int width, int height) {
|
|||||||
Texture t;
|
Texture t;
|
||||||
t.texture = (void*)(uintptr_t)(textureHandle);
|
t.texture = (void*)(uintptr_t)(textureHandle);
|
||||||
t.size = ImVec2((float)width,(float)height);
|
t.size = ImVec2((float)width,(float)height);
|
||||||
|
t.exif = tin.exif;
|
||||||
|
t.channels = tin.channels;
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -120,6 +212,43 @@ void RotateImage(Texture t) {
|
|||||||
delete[] tempBuffer;
|
delete[] tempBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture LoadTexture(const char * path)
|
||||||
|
{
|
||||||
|
const int channelCount = 4;
|
||||||
|
int imageFileChannelCount;
|
||||||
|
int width, height;
|
||||||
|
image = (uint8_t *)stbi_load(path, &width, &height, &imageFileChannelCount, channelCount);
|
||||||
|
|
||||||
|
if (image == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\nFailed to open %s\n", stbi_failure_reason(), path);
|
||||||
|
|
||||||
|
return {nullptr,{0,0}};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto exif = printExifData(path);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GLenum dataFormat = GL_RGBA;
|
||||||
|
GLuint textureHandle;
|
||||||
|
glGenTextures(1, &textureHandle);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureHandle);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, dataFormat, GL_UNSIGNED_BYTE, image);
|
||||||
|
|
||||||
|
Texture t;
|
||||||
|
t.texture = (void*)(uintptr_t)(textureHandle);
|
||||||
|
t.size = ImVec2((float)width,(float)height);
|
||||||
|
t.channels = channelCount;
|
||||||
|
t.exif = exif;
|
||||||
|
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const int MAX_ANNOATED_TEXELS = 10000;
|
const int MAX_ANNOATED_TEXELS = 10000;
|
||||||
|
|
||||||
@ -136,6 +265,7 @@ int main(int argc, char* argv[]) {
|
|||||||
bool GRID_ENABLED = false;
|
bool GRID_ENABLED = false;
|
||||||
bool AA_ENABLED = true;
|
bool AA_ENABLED = true;
|
||||||
bool SHOW_HELP = false;
|
bool SHOW_HELP = false;
|
||||||
|
bool SHOW_EXIF = false;
|
||||||
int MODE = 0;
|
int MODE = 0;
|
||||||
|
|
||||||
// Decide GL+GLSL versions
|
// Decide GL+GLSL versions
|
||||||
@ -252,11 +382,14 @@ int main(int argc, char* argv[]) {
|
|||||||
break;
|
break;
|
||||||
case SDL_SCANCODE_R:
|
case SDL_SCANCODE_R:
|
||||||
RotateImage(t);
|
RotateImage(t);
|
||||||
t = ReloadTexture(t.texture, t.size.y, t.size.x);
|
t = ReloadTexture(t, t.size.y, t.size.x);
|
||||||
break;
|
break;
|
||||||
case SDL_SCANCODE_Q:
|
case SDL_SCANCODE_Q:
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
|
case SDL_SCANCODE_E:
|
||||||
|
SHOW_EXIF = !SHOW_EXIF;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -284,7 +417,7 @@ int main(int argc, char* argv[]) {
|
|||||||
ImGui::SetNextWindowPos(viewport->Pos);
|
ImGui::SetNextWindowPos(viewport->Pos);
|
||||||
ImGui::SetNextWindowSize(viewport->Size);
|
ImGui::SetNextWindowSize(viewport->Size);
|
||||||
ImGui::Begin("Main", NULL,
|
ImGui::Begin("Main", NULL,
|
||||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
|
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||||
auto wSize = ImGui::GetContentRegionAvail();
|
auto wSize = ImGui::GetContentRegionAvail();
|
||||||
if (t.texture != 0) {
|
if (t.texture != 0) {
|
||||||
|
|
||||||
@ -364,11 +497,132 @@ int main(int argc, char* argv[]) {
|
|||||||
ImGui::Text("\tFloat Values");
|
ImGui::Text("\tFloat Values");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Text("h - show help popup");
|
ImGui::Text("h - show help popup");
|
||||||
|
ImGui::Text("e - toggle EXIF info");
|
||||||
|
ImGui::Separator();
|
||||||
ImGui::Text("q - quit");
|
ImGui::Text("q - quit");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Text("click anywhere to continue");
|
ImGui::Text("click anywhere to continue");
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
if (SHOW_EXIF && t.exif.CameraMake != "NULL") {
|
||||||
|
ImGuiWindowClass topmost;
|
||||||
|
topmost.ClassId = ImHashStr("TopMost");
|
||||||
|
topmost.ViewportFlagsOverrideSet = ImGuiViewportFlags_TopMost;
|
||||||
|
ImGui::SetNextWindowClass(&topmost);
|
||||||
|
ImGui::Begin("EXIF", NULL, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing);
|
||||||
|
if(ImGui::BeginTable("Hardware", 2)) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Make");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.CameraMake.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Model");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.CameraModel.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Lens");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.LensModel.c_str());
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if(ImGui::BeginTable("Photo", 2)) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Shutter Speed");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.ShutterSpeed.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("F-Stop");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.FNumber.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("ISO");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.ISO.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Focal Length");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.FocalLength.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Exposure Comp");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.ExposureBias.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Metering Mode");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.MeteringMode.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Flash");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.Flash.c_str());
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if(ImGui::BeginTable("Meta", 2)) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Date");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s %s", t.exif.TimeTaken.c_str(), t.exif.TimeTakenOffset.c_str());
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Dimensions");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%sx%s", t.exif.ImageDimensionX.c_str(), t.exif.ImageDimensiony.c_str());
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if(ImGui::BeginTable("Location", 2)) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Latitude");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s %s", t.exif.GPSLat.c_str(), t.exif.GPSLatref.c_str());
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Longitude");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s %s", t.exif.GPSLon.c_str(), t.exif.GPSLonref.c_str());
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("Press e to hide");
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
|
Loading…
Reference in New Issue
Block a user