From c85eca3fef5887b09fa404bea7f006d26f40b98f Mon Sep 17 00:00:00 2001 From: Sandrine Witt Date: Tue, 17 Nov 2020 09:54:36 +0100 Subject: [PATCH] Add option to copy iptc data when transplanting exif information --- doc/functions.rst | 3 ++- piexif/_common.py | 19 ++++++++++++++++++- piexif/_transplant.py | 6 ++++-- tests/images/01.jpg | Bin 1097 -> 4066 bytes tests/s_test.py | 19 +++++++++++++++++++ 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/doc/functions.rst b/doc/functions.rst index 5c14605..25db0bf 100644 --- a/doc/functions.rst +++ b/doc/functions.rst @@ -138,12 +138,13 @@ remove transplant ---------- -.. py:function:: piexif.transplant(filename1, filename2) +.. py:function:: piexif.transplant(filename1, filename2, include_iptc=False) Copies exif data from filename1 to filename2. :param str filename1: JPEG :param str filename2: JPEG + :param bool include_iptc: copy iptc data :: diff --git a/piexif/_common.py b/piexif/_common.py index 6069c60..165ab85 100644 --- a/piexif/_common.py +++ b/piexif/_common.py @@ -57,6 +57,7 @@ def read_exif_from_file(filename): f.close() return exif + def get_exif_seg(segments): """Returns Exif from JPEG meta data list """ @@ -66,7 +67,16 @@ def get_exif_seg(segments): return None -def merge_segments(segments, exif=b""): +def get_iptc_seg(segments): + """Returns iptc from JPEG meta data list + """ + for seg in segments: + if seg[0:2] == b"\xff\xed": + return seg + return None + + +def merge_segments(segments, exif=b"", iptc=b""): """Merges Exif with APP0 and APP1 manipulations. """ if segments[1][0:2] == b"\xff\xe0" and \ @@ -91,4 +101,11 @@ def merge_segments(segments, exif=b""): else: if exif: segments.insert(1, exif) + + if iptc: + if segments[4][0:2] == b"\xff\xed": + segments[4] = iptc + else: + segments.insert(4, iptc) + return b"".join(segments) diff --git a/piexif/_transplant.py b/piexif/_transplant.py index 0abf7f1..276ac1c 100644 --- a/piexif/_transplant.py +++ b/piexif/_transplant.py @@ -3,7 +3,7 @@ from ._common import * -def transplant(exif_src, image, new_file=None): +def transplant(exif_src, image, new_file=None, include_iptc=False): """ py:function:: piexif.transplant(filename1, filename2) @@ -22,6 +22,8 @@ def transplant(exif_src, image, new_file=None): if exif is None: raise ValueError("not found exif in input") + iptc = get_iptc_seg(segments) if include_iptc else b"" + output_file = False if image[0:2] == b"\xff\xd8": image_data = image @@ -30,7 +32,7 @@ def transplant(exif_src, image, new_file=None): image_data = f.read() output_file = True segments = split_into_segments(image_data) - new_data = merge_segments(segments, exif) + new_data = merge_segments(segments, exif, iptc) if isinstance(new_file, io.BytesIO): new_file.write(new_data) diff --git a/tests/images/01.jpg b/tests/images/01.jpg index 2b9ae905645dc405142547f6354357f2786b326f..c13dc39c4c223132b4a130c23e2c08382b4d5b6f 100644 GIT binary patch literal 4066 zcmeHKYj6`)6ux(N)1)b5n^I7qj?0!R;w0Imt&p9jojxd(AxmQ+tEghX52xDZ3K95gr%tiYV3IxzP*s~!UE=LS#7FY>fL3JDG8eU2F zi0jRGm8tK;YY_{3Sl8j^q4r!?=T?NhRIh?(cOHl$j@ZDOhJ^z1pn_0uZ?6*;(m`Mo z5R7lH=<`XUPxAVBk0{X#q4JTbd`#RoT4&%9k8w612M5PFQ{OZ0pt==+$Hps7eR7gR zb`lM)smTet&xxXlCMOH}G&VR9t7*o}-8Rh@^jUj>_pF!Z1|0FsY#qfZ1^qbT`d6$j z#q>JSD?vIa|DE?Ya;7yTbzHQzDv7jFSAD+BGN5Tm$?Z<0U2<3rDz1`thV`e91cH4U+?^rltqfKQT8S)8Z1R zq|}yDWKC&@F$Rsi_`Sjrj%mUkSV!Pa>{HBzSd3 z7!e|wVT>b0N*4}E;X>sW-bPDIThL-rQWGgACnA0!=L{?Tawet;O+89l<6FUTAf-fu znM9<~O^P0if*;ik2=^j**hpuByOdBqLaQ7xV>N~4)ZoQPh5D8&jCD^RRJu>!>k6f5xmt3aWnRT9t(Wuae1`qyZGSH5-Q>s%t*(ApW`$RGj} zNHy+5?5f&L)iCTZh^b~)Add7U)y#TiFSKmcOb$5~wL#TPBP#QVhpvJa-h!!6H@IPj>Km?KzriQ9wQua$w7GN3_MRO#?(Ds(F9Z!a+2@{r;rOd_uf6`pn{U1S z&dF2nzW4s=GiT>N{^ZloKL6s}mtS4@_Pg(Y`0=NofBBX0g3-yK1$TqlMZ91x!wko< zoR#pxOqLLLaF*4clFF8CR(bbQ!MoR1)jDzL@UhaGy6*GKf~gbsGfFp8MEeXM*DOKZLD9uCD;N?8?LfpkM z9pH-;J>6OTPB6Z%4>U2Y^BsuFU0z&UMx|02<$!$OxFIKRY#ldUDPDJ>bGe@l`s$fK zr+tt5g9!6Ohh9ii*=)YCK%MczSw>||W|pO{%$}>&s8NJxBt(rlwi~X>re%Yw34Zo- zrwc}smqP@cU%M-G{|%xkp33ENQ|e1L0mKVtVfg*J-)HE$Zkk5GiiE6S(CTVy4@aC> zqT7ktOLnqLJo0ckMnx+-BqM=YU-DCHp|Gh3Z YL$}oN49i2%T0O0p!N=#WdlD8;U(UE{4*&oF diff --git a/tests/s_test.py b/tests/s_test.py index 5d105de..fac801b 100644 --- a/tests/s_test.py +++ b/tests/s_test.py @@ -452,6 +452,25 @@ def test_transplant(self): piexif.load("transplant.jpg")) os.remove("transplant.jpg") + def test_transplant_with_iptc_data(self): + piexif.transplant(INPUT_FILE1, INPUT_FILE_PEN, "transplant.jpg", include_iptc=True) + i = Image.open("transplant.jpg") + i.close() + with open(INPUT_FILE1, 'rb') as f: + original_segments = _common.split_into_segments(f.read()) + with open("transplant.jpg", 'rb') as f: + copy_segments = _common.split_into_segments(f.read()) + + self.assertEqual( + _common.get_iptc_seg(original_segments), + _common.get_iptc_seg(copy_segments) + ) + self.assertNotEqual( + _common.get_iptc_seg(copy_segments), + None + ) + os.remove("transplant.jpg") + def test_transplant_m(self): """'transplant' on memory. """