mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-07-02 19:03:24 +03:00
Added possibility to save exif information in jpeg-files
This commit is contained in:
parent
54d4f5eb3c
commit
addf0f4d95
|
@ -465,6 +465,7 @@ def _save(im, fp, filename):
|
||||||
dpi[0], dpi[1],
|
dpi[0], dpi[1],
|
||||||
subsampling,
|
subsampling,
|
||||||
extra,
|
extra,
|
||||||
|
info.get("exif", "")
|
||||||
)
|
)
|
||||||
|
|
||||||
ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
|
ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
|
||||||
|
|
20
encode.c
20
encode.c
|
@ -520,11 +520,16 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
||||||
int streamtype = 0; /* 0=interchange, 1=tables only, 2=image only */
|
int streamtype = 0; /* 0=interchange, 1=tables only, 2=image only */
|
||||||
int xdpi = 0, ydpi = 0;
|
int xdpi = 0, ydpi = 0;
|
||||||
int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */
|
int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */
|
||||||
char* extra = NULL; int extra_size;
|
char* extra = NULL;
|
||||||
|
int extra_size;
|
||||||
|
char* rawExif = NULL;
|
||||||
|
int rawExifLen = 0;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ss|iiiiiiii"PY_ARG_BYTES_LENGTH,
|
if (!PyArg_ParseTuple(args, "ss|iiiiiiii"PY_ARG_BYTES_LENGTH,
|
||||||
&mode, &rawmode, &quality,
|
&mode, &rawmode, &quality,
|
||||||
&progressive, &smooth, &optimize, &streamtype,
|
&progressive, &smooth, &optimize, &streamtype,
|
||||||
&xdpi, &ydpi, &subsampling, &extra, &extra_size))
|
&xdpi, &ydpi, &subsampling, &extra, &extra_size,
|
||||||
|
&rawExif, &rawExifLen))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
encoder = PyImaging_EncoderNew(sizeof(JPEGENCODERSTATE));
|
encoder = PyImaging_EncoderNew(sizeof(JPEGENCODERSTATE));
|
||||||
|
@ -543,6 +548,15 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
||||||
} else
|
} else
|
||||||
extra = NULL;
|
extra = NULL;
|
||||||
|
|
||||||
|
if (rawExif && rawExifLen > 0) {
|
||||||
|
char* pp = malloc(rawExifLen);
|
||||||
|
if (!pp)
|
||||||
|
return PyErr_NoMemory();
|
||||||
|
memcpy(pp, rawExif, rawExifLen);
|
||||||
|
rawExif = pp;
|
||||||
|
} else
|
||||||
|
rawExif = NULL;
|
||||||
|
|
||||||
encoder->encode = ImagingJpegEncode;
|
encoder->encode = ImagingJpegEncode;
|
||||||
|
|
||||||
((JPEGENCODERSTATE*)encoder->state.context)->quality = quality;
|
((JPEGENCODERSTATE*)encoder->state.context)->quality = quality;
|
||||||
|
@ -555,6 +569,8 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
||||||
((JPEGENCODERSTATE*)encoder->state.context)->ydpi = ydpi;
|
((JPEGENCODERSTATE*)encoder->state.context)->ydpi = ydpi;
|
||||||
((JPEGENCODERSTATE*)encoder->state.context)->extra = extra;
|
((JPEGENCODERSTATE*)encoder->state.context)->extra = extra;
|
||||||
((JPEGENCODERSTATE*)encoder->state.context)->extra_size = extra_size;
|
((JPEGENCODERSTATE*)encoder->state.context)->extra_size = extra_size;
|
||||||
|
((JPEGENCODERSTATE*)encoder->state.context)->rawExif = rawExif;
|
||||||
|
((JPEGENCODERSTATE*)encoder->state.context)->rawExifLen = rawExifLen;
|
||||||
|
|
||||||
return (PyObject*) encoder;
|
return (PyObject*) encoder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,4 +101,7 @@ typedef struct {
|
||||||
|
|
||||||
int extra_offset;
|
int extra_offset;
|
||||||
|
|
||||||
|
int rawExifLen; /* EXIF data length */
|
||||||
|
char* rawExif; /* EXIF buffer pointer */
|
||||||
|
|
||||||
} JPEGENCODERSTATE;
|
} JPEGENCODERSTATE;
|
||||||
|
|
|
@ -205,10 +205,18 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
jpeg_start_compress(&context->cinfo, FALSE);
|
jpeg_start_compress(&context->cinfo, FALSE);
|
||||||
/* suppress extra section */
|
/* suppress extra section */
|
||||||
context->extra_offset = context->extra_size;
|
context->extra_offset = context->extra_size;
|
||||||
|
//add exif header
|
||||||
|
if (context->rawExifLen > 0)
|
||||||
|
jpeg_write_marker(&context->cinfo, JPEG_APP0+1, context->rawExif, context->rawExifLen);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* interchange stream */
|
/* interchange stream */
|
||||||
jpeg_start_compress(&context->cinfo, TRUE);
|
jpeg_start_compress(&context->cinfo, TRUE);
|
||||||
|
//add exif header
|
||||||
|
if (context->rawExifLen > 0)
|
||||||
|
jpeg_write_marker(&context->cinfo, JPEG_APP0+1, context->rawExif, context->rawExifLen);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state->state++;
|
state->state++;
|
||||||
|
|
4
py3.h
4
py3.h
|
@ -11,7 +11,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if PY_VERSION_HEX >= 0x03000000
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
#define PY_ARG_BYTES_LENGTH "y#"
|
#define PY_ARG_BYTES_LENGTH "y#y#"
|
||||||
|
|
||||||
/* Map PyInt -> PyLong */
|
/* Map PyInt -> PyLong */
|
||||||
#define PyInt_AsLong PyLong_AsLong
|
#define PyInt_AsLong PyLong_AsLong
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
#define PyInt_AS_LONG PyLong_AS_LONG
|
#define PyInt_AS_LONG PyLong_AS_LONG
|
||||||
|
|
||||||
#else /* PY_VERSION_HEX < 0x03000000 */
|
#else /* PY_VERSION_HEX < 0x03000000 */
|
||||||
#define PY_ARG_BYTES_LENGTH "s#"
|
#define PY_ARG_BYTES_LENGTH "s#s#"
|
||||||
|
|
||||||
#if !defined(KEEP_PY_UNICODE)
|
#if !defined(KEEP_PY_UNICODE)
|
||||||
/* Map PyUnicode -> PyString */
|
/* Map PyUnicode -> PyString */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user