Instantly share code, notes, and snippets.
Created
March 3, 2023 15:37
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save ashwanirathee/b38b11cb9f020315baf142e6cf246f20 to your computer and use it in GitHub Desktop.
LibExif Issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Test,TestImages | |
using JpegTurbo | |
include("../lib/LibExif.jl") | |
include("../src/utils.jl") | |
include("../src/read.jl") | |
FILE_BYTE_ORDER = LibExif.EXIF_BYTE_ORDER_INTEL | |
function init_tag(exif, ifd, tag) | |
exif1 = unsafe_load(exif) | |
entry = LibExif.exif_content_get_entry(exif1.ifd[ifd], tag) | |
if entry == C_NULL | |
entry = LibExif.exif_entry_new() | |
entry.tag = tag | |
LibExif.exif_content_add_entry(exif1.ifd[ifd], entry) | |
LibExif.exif_entry_initialize(entry, tag) | |
LibExif.exif_entry_unref(entry) | |
end | |
return entry | |
end | |
function set_value(entry, tagv) | |
if entry.tag in [ | |
LibExif.EXIF_TAG_COMPRESSION, | |
LibExif.EXIF_TAG_COLOR_SPACE, | |
LibExif.EXIF_TAG_SUBJECT_DISTANCE_RANGE, | |
LibExif.EXIF_TAG_ORIENTATION, | |
LibExif.EXIF_TAG_METERING_MODE, | |
LibExif.EXIF_TAG_SENSING_METHOD, | |
LibExif.EXIF_TAG_FLASH, | |
LibExif.EXIF_TAG_YCBCR_POSITIONING, | |
LibExif.EXIF_TAG_RESOLUTION_UNIT, | |
LibExif.EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT, | |
LibExif.EXIF_TAG_PLANAR_CONFIGURATION, | |
LibExif.EXIF_TAG_PHOTOMETRIC_INTERPRETATION, | |
LibExif.EXIF_TAG_CUSTOM_RENDERED, | |
LibExif.EXIF_TAG_EXPOSURE_MODE, | |
LibExif.EXIF_TAG_WHITE_BALANCE, | |
LibExif.EXIF_TAG_SCENE_CAPTURE_TYPE, | |
LibExif.EXIF_TAG_GAIN_CONTROL, | |
LibExif.EXIF_TAG_SATURATION, | |
LibExif.EXIF_TAG_CONTRAST, | |
LibExif.EXIF_TAG_SHARPNESS | |
] | |
LibExif.exif_set_short( | |
entry.data, | |
LibExif.EXIF_BYTE_ORDER_INTEL, | |
TagsDict[entry.tag][tagv], | |
) | |
elseif entry.tag == LibExif.EXIF_TAG_FLASH_PIX_VERSION | |
data = Dict{String,String}( | |
"FlashPix Version 1.0" => "0100\0", | |
"FlashPix Version 1.01" => "0101\0", | |
"Unknown FlashPix Version" => "0000\0", | |
) | |
unsafe_copyto!(entry.data, pointer(Vector{UInt8}(data[tagv])), 5) | |
elseif (entry.tag in [LibExif.EXIF_TAG_MAKE, LibExif.EXIF_TAG_ARTIST, LibExif.EXIF_TAG_MODEL]) | |
unsafe_copyto!(entry.data, pointer(Vector{UInt8}(tagv * "\0")), length(tagv) + 1) | |
elseif entry.tag in [ | |
LibExif.EXIF_TAG_PIXEL_Y_DIMENSION, | |
LibExif.EXIF_TAG_PIXEL_X_DIMENSION, | |
LibExif.EXIF_TAG_X_RESOLUTION, | |
LibExif.EXIF_TAG_Y_RESOLUTION, | |
LibExif.EXIF_TAG_IMAGE_WIDTH, | |
LibExif.EXIF_TAG_IMAGE_LENGTH, | |
] | |
LibExif.exif_set_long(entry.data, FILE_BYTE_ORDER, parse(Cuint, tagv)) | |
elseif entry.tag in [ | |
LibExif.EXIF_TAG_EXPOSURE_TIME, | |
LibExif.EXIF_TAG_COMPRESSED_BITS_PER_PIXEL, | |
LibExif.EXIF_TAG_APERTURE_VALUE, | |
LibExif.EXIF_TAG_MAX_APERTURE_VALUE, | |
LibExif.EXIF_TAG_FOCAL_LENGTH, | |
LibExif.EXIF_TAG_FOCAL_PLANE_X_RESOLUTION, | |
LibExif.EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION, | |
] | |
p = rationalize(parse(Float32, tagv);tol=0.1) | |
LibExif.exif_set_rational(entry.data,FILE_BYTE_ORDER, LibExif.ExifRational(p.num, p.den)) | |
elseif entry.tag in [LibExif.EXIF_TAG_SHUTTER_SPEED_VALUE, LibExif.EXIF_TAG_EXPOSURE_BIAS_VALUE] | |
p = Rational(parse(Float32, tagv)) | |
LibExif.exif_set_srational(entry.data, FILE_BYTE_ORDER, LibExif.ExifSRational(p.num, p.den)) | |
elseif entry.tag == LibExif.EXIF_TAG_FNUMBER | |
p = Rational(parse(Float32, split(tagv, "/")[2])) | |
LibExif.exif_set_rational(entry.data, FILE_BYTE_ORDER, LibExif.ExifRational(p.num, p.den)) | |
else | |
println("Tag Not Supported") | |
end | |
end | |
function set_value1(entry, tagv) | |
@info "Entry:" entry | |
# @info entry.format entry.tag | |
if unsafe_load(entry.format) == LibExif.EXIF_FORMAT_SHORT | |
# if(entry.tag in keys(TagsDict)) | |
# LibExif.exif_set_short(entry.data, LibExif.EXIF_BYTE_ORDER_INTEL, TagsDict[entry.tag][tagv]) | |
# else | |
# LibExif.exif_set_long(entry.data, FILE_BYTE_ORDER, parse(Cuint, tagv)) | |
# end | |
elseif unsafe_load(entry.format) == LibExif.EXIF_FORMAT_LONG | |
# LibExif.exif_set_long(entry.data, FILE_BYTE_ORDER, parse(Cuint, tagv)) | |
elseif unsafe_load(entry.format) == LibExif.EXIF_FORMAT_ASCII | |
# unsafe_copyto!(unsafe_load(entry.data), pointer(Vector{UInt8}(tagv * "\0")), length(tagv) + 1) | |
elseif unsafe_load(entry.format) == LibExif.EXIF_FORMAT_RATIONAL | |
# @info "Rational Case:" | |
# p = rationalize(parse(Float32, tagv);tol=0.1) | |
# LibExif.exif_set_rational(entry.data,FILE_BYTE_ORDER, LibExif.ExifRational(p.num, p.den)) | |
elseif unsafe_load(entry.format) == LibExif.EXIF_FORMAT_SRATIONAL | |
# p = Rational(parse(Float32, tagv)) | |
# LibExif.exif_set_srational(entry.data, FILE_BYTE_ORDER, LibExif.ExifSRational(p.num, p.den)) | |
else | |
# if unsafe_load(entry).format == LibExif.EXIF_FORMAT_UNDEFINED | |
@info "Undefined case: " tagv length(tagv) | |
@info "Value:" entry.size entry.components entry.format | |
unsafe_copyto!(entry.size, pointer(Vector{UInt32}([7])), 1) | |
unsafe_copyto!(entry.components, pointer(Vector{UInt32}([7])), 1) | |
unsafe_copyto!(entry.format, pointer(Vector{Main.LibExif.ExifFormat}([LibExif.EXIF_FORMAT_ASCII])), 1) | |
# entry1 = unsafe_load(entry) | |
# entry.size =7; | |
# entry.components = 7; | |
# entry.format = LibExif.EXIF_FORMAT_ASCII; | |
# @show entry.data | |
# mem = LibExif.exif_mem_new_default(); | |
# len = length(tagv)+1; | |
# buf = LibExif.exif_mem_alloc(mem, len); | |
# @info "Buf: " buf | |
# unsafe_copyto!(buf, pointer(Vector{UInt8}(tagv * "\0")), length(tagv) + 1) | |
# # @info "Important:" Int(unsafe_load(buf)) | |
# # # "EXIF_TAG_SUBJECT_AREA" => "36866", # undefined | |
# # # unsafe_copyto!(entry.data, pointer(Vector{UInt8}(tagv * "\0")), length(tagv)+1) | |
# # # unsafe_copyto!(entry.data, pointer(Vector{UInt8}(tagv * "\0")), length(tagv) + 1) | |
# # unsafe_copyto!(entry.data, Ref(buf), length(tagv) + 1) | |
# @info "Pointer to info:" pointer(Vector{UInt8}(tagv * "\0")) | |
# unsafe_copyto!(entry.data, pointer(Vector{UInt8}(tagv * "\0")), length(tagv)+1) | |
# @show pointer(buf) | |
# b = unsafe_load(entry.data) | |
# b = buf | |
# # @info "Length of tag: " length(tagv) + 1 | |
# entry.size =7; | |
# entry.components = 7; | |
# entry.format = LibExif.EXIF_FORMAT_ASCII; | |
# @show unsafe_load(entry.data) | |
# unsafe_copyto!(b, pointer(Vector{UInt8}(tagv * "\0")), length(tagv) + 1) | |
mem = LibExif.exif_mem_new_default() | |
len = sizeof(tagv)+1 # +1 for null byte | |
buf = convert(Ptr{UInt8}, LibExif.exif_mem_alloc(mem, len)) | |
unsafe_copyto!(buf, pointer(tagv), sizeof(tagv)) | |
unsafe_store!(buf, 0x0, len) | |
# unsafe_copyto!(entry.data, buf, 1) | |
@show entry.data buf | |
entry.data = buf | |
@show entry.data buf | |
@info "After entry.data = buf :" Int(unsafe_load(entry.data)) Int(unsafe_load(buf)) | |
end | |
end | |
function create_exif_data(tags) | |
exif = LibExif.exif_data_new() | |
LibExif.exif_data_set_option(exif, LibExif.EXIF_DATA_OPTION_FOLLOW_SPECIFICATION) | |
LibExif.exif_data_set_data_type(exif, LibExif.EXIF_DATA_TYPE_COMPRESSED) | |
LibExif.exif_data_set_byte_order(exif, LibExif.EXIF_BYTE_ORDER_INTEL) | |
LibExif.exif_data_fix(exif) | |
keys1 = keys(tags) | |
for i in keys1 | |
key = normalize_exif_flag(i) | |
x = LibExif.EXIF_DATA_TYPE_UNCOMPRESSED_CHUNKY | |
# indentify which ifds tag goes in | |
ifds = [ | |
LibExif.EXIF_IFD_0, | |
LibExif.EXIF_IFD_1, | |
LibExif.EXIF_IFD_EXIF, | |
LibExif.EXIF_IFD_GPS, | |
LibExif.EXIF_IFD_INTEROPERABILITY, | |
LibExif.EXIF_IFD_COUNT, | |
] | |
A = [LibExif.exif_tag_get_support_level_in_ifd(key, i, x) for i in ifds] | |
ifd = findfirst(==(LibExif.EXIF_SUPPORT_LEVEL_MANDATORY), A) | |
if ifd === nothing | |
ifd = findfirst(==(LibExif.EXIF_SUPPORT_LEVEL_OPTIONAL), A) | |
end | |
if key == LibExif.EXIF_TAG_YCBCR_POSITIONING | |
ifd = 1 | |
end | |
if key in [LibExif.EXIF_TAG_PIXEL_X_DIMENSION, LibExif.EXIF_TAG_PIXEL_Y_DIMENSION] | |
ifd = 3 | |
end | |
if ifd === nothing || issupported(i) == false | |
@info "Tag not supported currently or No Appropriate IFD found " key | |
continue | |
end | |
entry1 = init_tag(exif, ifd, key) | |
# entry = unsafe_load(entry1) | |
@info key issupported(i) findfirst(==(LibExif.EXIF_SUPPORT_LEVEL_OPTIONAL), A) findfirst(==(LibExif.EXIF_SUPPORT_LEVEL_MANDATORY), A) ifd | |
set_value1(entry1, tags[i]) | |
@show entry1.parent | |
@info "Exif:" unsafe_load(entry1) | |
end | |
return exif | |
end | |
function write_tags(filepath::AbstractString; img::AbstractArray, tags::Dict{String,String}) | |
# restricting filetype to .jpeg and .jpg | |
if (!(split(filepath,".")[2] in ["jpeg", "jpg"])) | |
throw(DomainError("Currently only jpeg and jpg files are supported for EXIF write operation.")) | |
end | |
data = jpeg_encode(img) | |
exif = create_exif_data(tags) | |
LibExif.exif_data_dump(exif); | |
exif_header = Vector{Cuchar}([0xff, 0xd8, 0xff, 0xe1]) | |
exif_data = Ref{Ptr{Cuchar}}() | |
exif_data_len = Cuint(length(exif_data)) | |
ref_exif_data_len = Ref(exif_data_len) | |
LibExif.exif_data_save_data(exif, exif_data, ref_exif_data_len) | |
groups_vec = unsafe_wrap(Array, exif_data[], 5000) | |
len = findfirst([0xff], groups_vec)[1] | |
groups_vec = groups_vec[1:max(len, 1)] | |
open(filepath, "w") do file | |
write(file, exif_header) # done | |
write(file, UInt8((len + 2) >> 8)) | |
write(file, UInt8((len + 2) & 0xff)) | |
write(file, groups_vec) | |
write(file, data[3:end]) | |
end | |
end | |
img = testimage("mandrill") | |
tags = Dict{String, String}( | |
# "EXIF_TAG_INTEROPERABILITY_INDEX" => "R98" | |
# EXIF_TAG_INTEROPERABILITY_VERSION = 2 | |
# EXIF_TAG_NEW_SUBFILE_TYPE = 254 | |
# "EXIF_TAG_IMAGE_WIDTH" => "100", # WORK | |
# "EXIF_TAG_IMAGE_LENGTH" => "100", # WORK | |
# "EXIF_TAG_BITS_PER_SAMPLE" => "258", | |
# "EXIF_TAG_COMPRESSION" => "Uncompressed", # WORK | |
# "EXIF_TAG_PHOTOMETRIC_INTERPRETATION" => "RGB", # WORK | |
# "EXIF_TAG_FILL_ORDER" => "266" | |
# "EXIF_TAG_DOCUMENT_NAME" => "docname", # NOT in EXIF 2.2 | |
# "EXIF_TAG_IMAGE_DESCRIPTION" => "270", # WORK | |
# "EXIF_TAG_MAKE" => "Canon", # WORK | |
# "EXIF_TAG_MODEL" => "272" # WORK | |
# "EXIF_TAG_STRIP_OFFSETS" => "273" # format undefined: Not used in JPEG | |
# "EXIF_TAG_ORIENTATION" => "Top-left" # WORK | |
# "EXIF_TAG_SAMPLES_PER_PIXEL" => "8" # WORK | |
# "EXIF_TAG_ROWS_PER_STRIP" => "278" # format undefined | |
# "EXIF_TAG_STRIP_BYTE_COUNTS" => "279" # format undefined | |
# "EXIF_TAG_X_RESOLUTION" => "100", # WORK | |
# "EXIF_TAG_Y_RESOLUTION" => "100", # WORK | |
# "EXIF_TAG_PLANAR_CONFIGURATION" => "Planar format" # WORK | |
# "EXIF_TAG_RESOLUTION_UNIT" => "Inch" # WORK | |
# "EXIF_TAG_TRANSFER_FUNCTION" => "301" # format undefined | |
# "EXIF_TAG_SOFTWARE" => "305", # WORK | |
# "EXIF_TAG_DATE_TIME" => "306", # WORK | |
"EXIF_TAG_ARTIST" => "315", # WORK | |
# "EXIF_TAG_WHITE_POINT" => "318" # WORK | |
# "EXIF_TAG_PRIMARY_CHROMATICITIES" => "319" # WORK | |
# "EXIF_TAG_SUB_IFDS" => "330" # support issues | |
# "EXIF_TAG_TRANSFER_RANGE" => "342" # support issues | |
# "EXIF_TAG_JPEG_PROC" => "512" # support issues | |
# "EXIF_TAG_JPEG_INTERCHANGE_FORMAT" => "513", # support issues | |
# "EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH" => "514", # support issues | |
# "EXIF_TAG_YCBCR_COEFFICIENTS" => "529", # support issues | |
# "EXIF_TAG_YCBCR_SUB_SAMPLING" => "530" # support issues | |
# "EXIF_TAG_YCBCR_POSITIONING" => "Co-sited", # WORK | |
# "EXIF_TAG_REFERENCE_BLACK_WHITE" => "532", # WORK | |
# "EXIF_TAG_XML_PACKET" => "700" # support issues | |
# "EXIF_TAG_RELATED_IMAGE_FILE_FORMAT" => "4096", # support issues | |
# "EXIF_TAG_RELATED_IMAGE_WIDTH" => "4097", # support issues | |
# "EXIF_TAG_RELATED_IMAGE_LENGTH" => "4098", # support issues | |
# "EXIF_TAG_IMAGE_DEPTH" => "32997" # support issues | |
# "EXIF_TAG_CFA_REPEAT_PATTERN_DIM" => "33421", # support issues | |
# "EXIF_TAG_CFA_PATTERN" => "33421", # support issues | |
# "EXIF_TAG_BATTERY_LEVEL" => "33421", # support issues | |
# "EXIF_TAG_COPYRIGHT"=> "33421", # WORK | |
# "EXIF_TAG_EXPOSURE_TIME" => "33421", # WORK | |
# "EXIF_TAG_FNUMBER" => "33421", # WORK | |
# "EXIF_TAG_IPTC_NAA" => "33421", # support issues | |
# "EXIF_TAG_IMAGE_RESOURCES" => "33421", # support issues | |
# "EXIF_TAG_EXIF_IFD_POINTER" => "33421", # support issues | |
# "EXIF_TAG_INTER_COLOR_PROFILE" => "33421", # support issues | |
# "EXIF_TAG_EXPOSURE_PROGRAM" => "34850", # WORK | |
# "EXIF_TAG_SPECTRAL_SENSITIVITY" => "34850", # undefined | |
# "EXIF_TAG_GPS_INFO_IFD_POINTER" => "34850", # support | |
# "EXIF_TAG_ISO_SPEED_RATINGS" => "34850", # WORK | |
# "EXIF_TAG_OECF" => "34850", # undefined format | |
# "EXIF_TAG_TIME_ZONE_OFFSET" => "34850", # support | |
# "EXIF_TAG_SENSITIVITY_TYPE" => "34850", # WORK | |
# "EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY" => "34850", # undefined | |
# "EXIF_TAG_RECOMMENDED_EXPOSURE_INDEX" => "34850", #undefined | |
# "EXIF_TAG_ISO_SPEED" => "34850", # undefined format | |
# "EXIF_TAG_ISO_SPEEDLatitudeYYY" => "34850", # undefined format | |
# "EXIF_TAG_ISO_SPEEDLatitudeZZZ" => "34850", #undefined format | |
# "EXIF_TAG_EXIF_VERSION" => "34850", # undefined format | |
# "EXIF_TAG_DATE_TIME_ORIGINAL" => "36867", # works | |
# "EXIF_TAG_DATE_TIME_DIGITIZED" => "36867", # undefined | |
# "EXIF_TAG_OFFSET_TIME" => "36867", # undefined | |
# "EXIF_TAG_OFFSET_TIME_ORIGINAL" => "36867", # undefined | |
# "EXIF_TAG_OFFSET_TIME_DIGITIZED" => "36867", # undefined | |
# "EXIF_TAG_COMPONENTS_CONFIGURATION" => "36867", # support issue | |
# "EXIF_TAG_COMPRESSED_BITS_PER_PIXEL" => "36867", # support issue | |
# "EXIF_TAG_SHUTTER_SPEED_VALUE" => "36867", # work | |
# "EXIF_TAG_APERTURE_VALUE" => "36867", # work | |
# "EXIF_TAG_BRIGHTNESS_VALUE" => "36867", # work | |
# "EXIF_TAG_EXPOSURE_BIAS_VALUE" => "36867", # work | |
# "EXIF_TAG_MAX_APERTURE_VALUE" => "36867", # work | |
# "EXIF_TAG_SUBJECT_DISTANCE" => "36867", # work | |
"EXIF_TAG_FOCAL_LENGTH" => "36867", # work | |
"EXIF_TAG_SUBJECT_AREA" => "36866", # undefined | |
# "EXIF_TAG_TIFF_EP_STANDARD_ID" => "36867", # support issues | |
# "EXIF_TAG_MAKER_NOTE" => "36867", #undefined | |
# "EXIF_TAG_USER_COMMENT" => "36867", # undefined | |
# "EXIF_TAG_SUB_SEC_TIME" => "36867", # read only error | |
# "EXIF_TAG_SUB_SEC_TIME_ORIGINAL" => "36867", # read only error | |
# "EXIF_TAG_SUB_SEC_TIME_DIGITIZED" => "36867", # read only | |
# "EXIF_TAG_XP_TITLE" => "36867", # undefined | |
# "EXIF_TAG_XP_COMMENT" => "36867", # undefined | |
# "EXIF_TAG_XP_AUTHOR" => "36867", # undefined | |
# "EXIF_TAG_XP_KEYWORDS" => "36867", # undefined | |
# "EXIF_TAG_XP_SUBJECT" => "36867", #undefined | |
# "EXIF_TAG_FLASH_PIX_VERSION" => "36867", # undefined | |
# "EXIF_TAG_COLOR_SPACE" => "36867", # work | |
# "EXIF_TAG_PIXEL_X_DIMENSION" => "36867", # work | |
# "EXIF_TAG_PIXEL_Y_DIMENSION" => "36867", # work | |
# "EXIF_TAG_RELATED_SOUND_FILE" => "36867", # undefined | |
# "EXIF_TAG_INTEROPERABILITY_IFD_POINTER" => "36867", # support issues | |
# "EXIF_TAG_FLASH_ENERGY" => "36867", # work | |
# "EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE" => "36867", # undefined | |
# "EXIF_TAG_FOCAL_PLANE_X_RESOLUTION" => "36867", # WORK | |
# "EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION" => "36867", # WORK | |
# "EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT" => "36867", # WORK | |
# "EXIF_TAG_SUBJECT_LOCATION" => "36867", # work | |
# "EXIF_TAG_EXPOSURE_INDEX" => "36867", # work | |
# "EXIF_TAG_SENSING_METHOD" => "36867", # WORK | |
# "EXIF_TAG_FILE_SOURCE" => "36867", # undefined | |
# "EXIF_TAG_SCENE_TYPE" => "41729", # undefined | |
# "EXIF_TAG_NEW_CFA_PATTERN" => "41729", # undefined | |
# "EXIF_TAG_CUSTOM_RENDERED" => "41729", # work | |
# "EXIF_TAG_EXPOSURE_MODE" => "41729", # work | |
# "EXIF_TAG_WHITE_BALANCE" => "41729", # work | |
# "EXIF_TAG_DIGITAL_ZOOM_RATIO" => "41729", # work | |
# "EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM" => "41729", # work | |
# "EXIF_TAG_SCENE_CAPTURE_TYPE" => "41729", # work | |
# "EXIF_TAG_GAIN_CONTROL" => "41729", # work | |
# "EXIF_TAG_CONTRAST" => "41729", # work | |
# "EXIF_TAG_SATURATION" => "41729", # work | |
# "EXIF_TAG_SHARPNESS" => "41729", # work | |
# "EXIF_TAG_DEVICE_SETTING_DESCRIPTION" => "41729", # undefined | |
# "EXIF_TAG_SUBJECT_DISTANCE_RANGE" => "41729", # work | |
# "EXIF_TAG_IMAGE_UNIQUE_ID" => "41729", # undefined | |
# "EXIF_TAG_CAMERA_OWNER_NAME" => "41729", # undefined | |
# "EXIF_TAG_BODY_SERIAL_NUMBER" => "41729", # undefined | |
# "EXIF_TAG_LENS_SPECIFICATION" => "41729", # undefined | |
# "EXIF_TAG_LENS_MAKE" => "41729", # undefined | |
# "EXIF_TAG_LENS_MODEL" => "41729", # undefined | |
# "EXIF_TAG_LENS_SERIAL_NUMBER" => "41729", # undefined | |
# "EXIF_TAG_COMPOSITE_IMAGE" => "41729", # undefined | |
# "EXIF_TAG_SOURCE_IMAGE_NUMBER_OF_COMPOSITE_IMAGE"=> "41729", # undefined | |
# "EXIF_TAG_SOURCE_EXPOSURE_TIMES_OF_COMPOSITE_IMAGE" => "41729", # undefined | |
# "EXIF_TAG_GAMMA" => "41729", #undefined | |
# "EXIF_TAG_PRINT_IMAGE_MATCHING" => "41729", # support issues | |
# "EXIF_TAG_PADDING" => "41729", # undefined | |
) | |
write_tags("test.jpg"; img, tags=tags) | |
@test read_tags("test.jpg") == tags |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment