Skip to content

Commit

Permalink
Merge pull request #345 from fredeastside/more_exif_data
Browse files Browse the repository at this point in the history
feat: add more exif data to metadata
  • Loading branch information
h2non authored Aug 1, 2020
2 parents 9b82aec + b38ffd4 commit af781a3
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 6 deletions.
20 changes: 19 additions & 1 deletion metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
38 changes: 38 additions & 0 deletions metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Binary file added testdata/test_exif.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added testdata/test_exif_canon.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions vips.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
43 changes: 38 additions & 5 deletions vips.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit af781a3

Please sign in to comment.