Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions CMakeMod/FindExif.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# - Try to find LibExif
# Once done this will define
# Exif_FOUND - System has LibExif
# Exif_INCLUDE_DIRS - The LibExif include directories
# Exif_LIBRARIES - The libraries needed to use LibExif
# Exif_DEFINITIONS - Compiler switches required for using LibExif

find_package(PkgConfig)
pkg_check_modules(PC_Exif QUIET libExif)
set(Exif_DEFINITIONS ${PC_Exif_CFLAGS_OTHER})

find_path(Exif_INCLUDE_DIR exif-utils.h
HINTS ${PC_Exif_INCLUDEDIR} ${PC_Exif_INCLUDE_DIRS}
PATH_SUFFIXES libexif )

find_library(Exif_LIBRARY NAMES exif
HINTS ${PC_Exif_LIBDIR} ${PC_Exif_LIBRARY_DIRS} )

set(Exif_LIBRARIES ${Exif_LIBRARY} )
set(Exif_INCLUDE_DIRS ${Exif_INCLUDE_DIR} )

include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set Exif_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(Exif DEFAULT_MSG
Exif_LIBRARY Exif_INCLUDE_DIR)

mark_as_advanced(Exif_INCLUDE_DIR Exif_LIBRARY )
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ All captured with Nikon D5100, raw processed by Rawtherapee, then assembled by T
## Build

This project is written in C++ with usage of QT framework and some other libraries
(ImageMagic, VidStab, V4L, GPHOTO2).
(ImageMagic, VidStab, V4L, GPHOTO2, exif).
I invest effort to create tools multiplatform, but I tested it on Ubuntu Linux only.
Moreover, V4L is Linux-only api.
It uses avconv or ffmpeg to build final videos.
Expand Down
12 changes: 9 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ FIND_PACKAGE(Qt5 REQUIRED COMPONENTS Core Multimedia)
FIND_PACKAGE(ImageMagick REQUIRED COMPONENTS Magick++ MagickCore)
FIND_PACKAGE(VidStab REQUIRED)
FIND_PACKAGE(V4L REQUIRED)
FIND_PACKAGE(GPHOTO2 REQUIRED)
FIND_PACKAGE(GPHOTO2 REQUIRED)
FIND_PACKAGE(Exif REQUIRED)

set(DESCRIBE_CMD "git describe --tags --dirty=+dirty --match 'v[0-9]*' | sed -E 's/^v//' ")
execute_process(
Expand All @@ -33,7 +34,8 @@ include_directories(
${VIDSTAB_INCLUDE_DIRS}
${CMAKE_CURRENT_BINARY_DIR} # timelapse_version.h
${V4L_INCLUDE_DIRS}
${GPHOTO2_INCLUDE_DIR})
${GPHOTO2_INCLUDE_DIR}
${Exif_INCLUDE_DIRS})

# enable warnings
ADD_DEFINITIONS( -Wall -Wextra -pedantic -fPIC)
Expand Down Expand Up @@ -74,6 +76,9 @@ message(STATUS "V4L_FOUND: ${V4L_FOUND}")
message(STATUS "GPHOTO2_FOUND: ${GPHOTO2_FOUND}")
message(STATUS "GPHOTO2_INCLUDE_DIR: ${GPHOTO2_INCLUDE_DIR}")
message(STATUS "GPHOTO2_LIBRARIES: ${GPHOTO2_LIBRARIES}")
message(STATUS "Exif_FOUND: ${Exif_FOUND}")
message(STATUS "Exif_INCLUDE_DIR: ${Exif_INCLUDE_DIR}")
message(STATUS "Exif_LIBRARIES: ${Exif_LIBRARIES}")

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
Expand Down Expand Up @@ -164,7 +169,8 @@ target_link_libraries(timelapse
${ImageMagick_LIBRARIES} # Magick++-6.Q16
${VIDSTAB_LIBRARIES}
${V4L_LIBRARIES}
${GPHOTO2_LIBRARIES})
${GPHOTO2_LIBRARIES}
${Exif_LIBRARIES})

target_link_libraries(timelapse_assembly
timelapse
Expand Down
42 changes: 36 additions & 6 deletions src/capture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <vector>
#include <utility>

#include <exif-data.h>

namespace timelapse {

AdaptiveShutterSpeedAlg::AdaptiveShutterSpeedAlg(
Expand Down Expand Up @@ -374,13 +376,41 @@ void TimeLapseCapture::onImageCaptured(QString format, Magick::Blob blob, Magick
shutterSpdAlg->update(capturedImage);
}

QDateTime now = QDateTime::currentDateTime();
QString exifDateTime = now.toString("yyyy:MM:dd HH:mm:ss");\
if (capturedImage.attribute("EXIF:DateTime").length() == 0) {
QDateTime now = QDateTime::currentDateTime();
QString exifDateTime = now.toString("yyyy:MM:dd HH:mm:ss");

Magick::Blob profile = capturedImage.exifProfile();
ExifData *data = exif_data_new();

exif_data_set_option(data, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
exif_data_set_data_type(data, EXIF_DATA_TYPE_COMPRESSED);
exif_data_set_byte_order(data, EXIF_BYTE_ORDER_INTEL);

exif_data_load_data(data, static_cast<const unsigned char *>(profile.data()), profile.length());

// ImageMagick don't support writing of exif data
// TODO: setup exif timestamp correctly
capturedImage.attribute("EXIF:DateTime", exifDateTime.toStdString());
//capturedImage.defineValue("EXIF", "DateTime", exifDateTime.toStdString());
ExifMem *exifMem = exif_mem_new_default();
ExifEntry *pE = exif_entry_new();
exif_content_add_entry(data->ifd[EXIF_IFD_0], pE);
exif_entry_initialize(pE, EXIF_TAG_DATE_TIME);
std::string dateStr = exifDateTime.toStdString();
pE->data = static_cast<unsigned char *>(exif_mem_alloc(exifMem, dateStr.length() +1 +8));
memcpy(pE->data, dateStr.c_str(), dateStr.length() +1);
//memcpy(pE->data, "ASCII\0\0\0", 8);
//memcpy(pE->data+8, dateStr.c_str(), dateStr.length() +1);

unsigned char *d;
unsigned int ds;

exif_data_dump(data);
exif_data_save_data(data, &d, &ds);
profile = Magick::Blob(d, ds);
capturedImage.exifProfile(profile);

exif_entry_unref(pE);
exif_mem_free(exifMem, d);
exif_data_free(data);
}

capturedImage.compressType(Magick::JPEGCompression);
capturedImage.magick("JPEG");
Expand Down