add more exif data to metadata

master
fredrsf 5 years ago
parent 9b82aecec1
commit b38ffd41d1

@ -22,6 +22,15 @@ type ImageMetadata struct {
Space string
Colourspace string
Size ImageSize
EXIF EXIF
}
type EXIF struct {
Make string
Model string
Orientation int
Software string
Datetime string
}
// Size returns the image size by width and height pixels.
@ -63,14 +72,23 @@ func Metadata(buf []byte) (ImageMetadata, error) {
Height: int(image.Ysize),
}
orientation := vipsExifOrientation(image)
metadata := ImageMetadata{
Size: size,
Channels: int(image.Bands),
Orientation: vipsExifOrientation(image),
Orientation: orientation,
Alpha: vipsHasAlpha(image),
Profile: vipsHasProfile(image),
Space: vipsSpace(image),
Type: ImageTypeName(imageType),
EXIF: EXIF{
Make: vipsExifMake(image),
Model: vipsExifModel(image),
Orientation: orientation,
Software: vipsExifSoftware(image),
Datetime: vipsExifDatetime(image),
},
}
return metadata, nil

@ -89,6 +89,44 @@ func TestImageInterpretation(t *testing.T) {
}
}
func TestEXIF(t *testing.T) {
files := []struct {
name string
make string
model string
orientation int
software string
datetime string
}{
{"test.jpg", "", "", 0, "", ""},
{"exif/Landscape_1.jpg", "", "", 1, "", ""},
{"test_exif.jpg", "Jolla", "Jolla", 1, "", "2014:09:21 16:00:56"},
{"test_exif_canon.jpg", "Canon", "Canon EOS 40D", 1, "GIMP 2.4.5", "2008:07:31 10:38:11"},
}
for _, file := range files {
metadata, err := Metadata(readFile(file.name))
if err != nil {
t.Fatalf("Cannot read the image: %s -> %s", file.name, err)
}
if metadata.EXIF.Make != file.make {
t.Fatalf("Unexpected image exif make: %s != %s", metadata.EXIF.Make, file.make)
}
if metadata.EXIF.Model != file.model {
t.Fatalf("Unexpected image exif model: %s != %s", metadata.EXIF.Model, file.model)
}
if metadata.EXIF.Orientation != file.orientation {
t.Fatalf("Unexpected image exif orientation: %d != %d", metadata.EXIF.Orientation, file.orientation)
}
if metadata.EXIF.Software != file.software {
t.Fatalf("Unexpected image exif software: %s != %s", metadata.EXIF.Software, file.software)
}
if metadata.EXIF.Datetime != file.datetime {
t.Fatalf("Unexpected image exif datetime: %s != %s", metadata.EXIF.Datetime, file.datetime)
}
}
}
func TestColourspaceIsSupported(t *testing.T) {
files := []struct {
name string

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

@ -215,10 +215,33 @@ func VipsIsTypeSupportedSave(t ImageType) bool {
return false
}
func vipsExifMake(image *C.VipsImage) string {
return vipsExifShort(C.GoString(C.vips_exif_make(image)))
}
func vipsExifModel(image *C.VipsImage) string {
return vipsExifShort(C.GoString(C.vips_exif_model(image)))
}
func vipsExifOrientation(image *C.VipsImage) int {
return int(C.vips_exif_orientation(image))
}
func vipsExifSoftware(image *C.VipsImage) string {
return vipsExifShort(C.GoString(C.vips_exif_software(image)))
}
func vipsExifDatetime(image *C.VipsImage) string {
return vipsExifShort(C.GoString(C.vips_exif_datetime(image)))
}
func vipsExifShort(s string) string {
if strings.Contains(s, " (") {
return s[:strings.Index(s, "(")-1]
}
return s
}
func vipsHasAlpha(image *C.VipsImage) bool {
return int(C.has_alpha_channel(image)) > 0
}

@ -18,7 +18,11 @@
#define VIPS_ANGLE_D270 VIPS_ANGLE_270
#endif
#define EXIF_IFD0_MAKE "exif-ifd0-Make"
#define EXIF_IFD0_MODEL "exif-ifd0-Model"
#define EXIF_IFD0_ORIENTATION "exif-ifd0-Orientation"
#define EXIF_IFD0_SOFTWARE "exif-ifd0-Software"
#define EXIF_IFD0_DATETIME "exif-ifd0-DateTime"
#define INT_TO_GBOOLEAN(bool) (bool > 0 ? TRUE : FALSE)
@ -218,19 +222,48 @@ vips_rotate_bridge(VipsImage *in, VipsImage **out, int angle) {
}
}
int
vips_exif_orientation(VipsImage *image) {
int orientation = 0;
const char *
vips_exif_tag(VipsImage *image, const char *tag) {
const char *exif;
if (
vips_image_get_typeof(image, EXIF_IFD0_ORIENTATION) != 0 &&
!vips_image_get_string(image, EXIF_IFD0_ORIENTATION, &exif)
vips_image_get_typeof(image, tag) != 0 &&
!vips_image_get_string(image, tag, &exif)
) {
return &exif[0];
}
return "";
}
const char *
vips_exif_make(VipsImage *image) {
return vips_exif_tag(image, EXIF_IFD0_MAKE);
}
const char *
vips_exif_model(VipsImage *image) {
return vips_exif_tag(image, EXIF_IFD0_MODEL);
}
int
vips_exif_orientation(VipsImage *image) {
int orientation = 0;
const char *exif = vips_exif_tag(image, EXIF_IFD0_ORIENTATION);
if (strcmp(exif, "")) {
orientation = atoi(&exif[0]);
}
return orientation;
}
const char *
vips_exif_software(VipsImage *image) {
return vips_exif_tag(image, EXIF_IFD0_SOFTWARE);
}
const char *
vips_exif_datetime(VipsImage *image) {
return vips_exif_tag(image, EXIF_IFD0_DATETIME);
}
int
interpolator_window_size(char const *name) {
VipsInterpolate *interpolator = vips_interpolate_new(name);

Loading…
Cancel
Save