mirror of
https://github.com/talgo-cloud/bimg.git
synced 2026-03-07 13:38:16 -08:00
add more exif data to metadata
This commit is contained in:
parent
9b82aecec1
commit
b38ffd41d1
6 changed files with 118 additions and 6 deletions
20
metadata.go
20
metadata.go
|
|
@ -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
|
||||
|
|
|
|||
BIN
testdata/test_exif.jpg
vendored
Normal file
BIN
testdata/test_exif.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 793 KiB |
BIN
testdata/test_exif_canon.jpg
vendored
Normal file
BIN
testdata/test_exif_canon.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
23
vips.go
23
vips.go
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
43
vips.h
43
vips.h
|
|
@ -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) {
|
|||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
vips_exif_tag(VipsImage *image, const char *tag) {
|
||||
const char *exif;
|
||||
if (
|
||||
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;
|
||||
if (
|
||||
vips_image_get_typeof(image, EXIF_IFD0_ORIENTATION) != 0 &&
|
||||
!vips_image_get_string(image, EXIF_IFD0_ORIENTATION, &exif)
|
||||
) {
|
||||
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…
Add table
Add a link
Reference in a new issue