You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
9.5 KiB

package bimg
/*
#cgo pkg-config: vips
#include "vips/vips.h"
*/
import "C"
// Common EXIF fields for data extraction
const (
Make = "exif-ifd0-Make"
Model = "exif-ifd0-Model"
Orientation = "exif-ifd0-Orientation"
XResolution = "exif-ifd0-XResolution"
YResolution = "exif-ifd0-YResolution"
ResolutionUnit = "exif-ifd0-ResolutionUnit"
Software = "exif-ifd0-Software"
Datetime = "exif-ifd0-DateTime"
YCbCrPositioning = "exif-ifd0-YCbCrPositioning"
Compression = "exif-ifd1-Compression"
ExposureTime = "exif-ifd2-ExposureTime"
FNumber = "exif-ifd2-FNumber"
ExposureProgram = "exif-ifd2-ExposureProgram"
ISOSpeedRatings = "exif-ifd2-ISOSpeedRatings"
ExifVersion = "exif-ifd2-ExifVersion"
DateTimeOriginal = "exif-ifd2-DateTimeOriginal"
DateTimeDigitized = "exif-ifd2-DateTimeDigitized"
ComponentsConfiguration = "exif-ifd2-ComponentsConfiguration"
ShutterSpeedValue = "exif-ifd2-ShutterSpeedValue"
ApertureValue = "exif-ifd2-ApertureValue"
BrightnessValue = "exif-ifd2-BrightnessValue"
ExposureBiasValue = "exif-ifd2-ExposureBiasValue"
MeteringMode = "exif-ifd2-MeteringMode"
Flash = "exif-ifd2-Flash"
FocalLength = "exif-ifd2-FocalLength"
SubjectArea = "exif-ifd2-SubjectArea"
MakerNote = "exif-ifd2-MakerNote"
SubSecTimeOriginal = "exif-ifd2-SubSecTimeOriginal"
SubSecTimeDigitized = "exif-ifd2-SubSecTimeDigitized"
ColorSpace = "exif-ifd2-ColorSpace"
PixelXDimension = "exif-ifd2-PixelXDimension"
PixelYDimension = "exif-ifd2-PixelYDimension"
SensingMethod = "exif-ifd2-SensingMethod"
SceneType = "exif-ifd2-SceneType"
ExposureMode = "exif-ifd2-ExposureMode"
WhiteBalance = "exif-ifd2-WhiteBalance"
FocalLengthIn35mmFilm = "exif-ifd2-FocalLengthIn35mmFilm"
SceneCaptureType = "exif-ifd2-SceneCaptureType"
GPSLatitudeRef = "exif-ifd3-GPSLatitudeRef"
GPSLatitude = "exif-ifd3-GPSLatitude"
GPSLongitudeRef = "exif-ifd3-GPSLongitudeRef"
GPSLongitude = "exif-ifd3-GPSLongitude"
GPSAltitudeRef = "exif-ifd3-GPSAltitudeRef"
GPSAltitude = "exif-ifd3-GPSAltitude"
GPSSpeedRef = "exif-ifd3-GPSSpeedRef"
GPSSpeed = "exif-ifd3-GPSSpeed"
GPSImgDirectionRef = "exif-ifd3-GPSImgDirectionRef"
GPSImgDirection = "exif-ifd3-GPSImgDirection"
GPSDestBearingRef = "exif-ifd3-GPSDestBearingRef"
GPSDestBearing = "exif-ifd3-GPSDestBearing"
GPSDateStamp = "exif-ifd3-GPSDateStamp"
)
// ImageSize represents the image width and height values
type ImageSize struct {
Width int
Height int
}
// ImageMetadata represents the basic metadata fields
type ImageMetadata struct {
Orientation int
Channels int
Alpha bool
Profile bool
Type string
Space string
Colourspace string
Size ImageSize
EXIF EXIF
}
// EXIF image metadata
type EXIF struct {
Make string
Model string
Orientation int
XResolution string
YResolution string
ResolutionUnit int
Software string
Datetime string
YCbCrPositioning int
Compression int
ExposureTime string
FNumber string
ExposureProgram int
ISOSpeedRatings int
ExifVersion string
DateTimeOriginal string
DateTimeDigitized string
ComponentsConfiguration string
ShutterSpeedValue string
ApertureValue string
BrightnessValue string
ExposureBiasValue string
MeteringMode int
Flash int
FocalLength string
SubjectArea string
MakerNote string
SubSecTimeOriginal string
SubSecTimeDigitized string
ColorSpace int
PixelXDimension int
PixelYDimension int
SensingMethod int
SceneType string
ExposureMode int
WhiteBalance int
FocalLengthIn35mmFilm int
SceneCaptureType int
GPSLatitudeRef string
GPSLatitude string
GPSLongitudeRef string
GPSLongitude string
GPSAltitudeRef string
GPSAltitude string
GPSSpeedRef string
GPSSpeed string
GPSImgDirectionRef string
GPSImgDirection string
GPSDestBearingRef string
GPSDestBearing string
GPSDateStamp string
}
// Size returns the image size by width and height pixels.
func Size(buf []byte) (ImageSize, error) {
metadata, err := Metadata(buf)
if err != nil {
return ImageSize{}, err
}
return ImageSize{
Width: int(metadata.Size.Width),
Height: int(metadata.Size.Height),
}, nil
}
// ColourspaceIsSupported checks if the image colourspace is supported by libvips.
func ColourspaceIsSupported(buf []byte) (bool, error) {
return vipsColourspaceIsSupportedBuffer(buf)
}
// ImageInterpretation returns the image interpretation type.
// See: https://libvips.github.io/libvips/API/current/VipsImage.html#VipsInterpretation
func ImageInterpretation(buf []byte) (Interpretation, error) {
return vipsInterpretationBuffer(buf)
}
// Metadata returns the image metadata (size, type, alpha channel, profile, EXIF orientation...).
func Metadata(buf []byte) (ImageMetadata, error) {
defer C.vips_thread_shutdown()
image, imageType, err := vipsRead(buf)
if err != nil {
return ImageMetadata{}, err
}
defer C.g_object_unref(C.gpointer(image))
size := ImageSize{
Width: int(image.Xsize),
Height: int(image.Ysize),
}
orientation := vipsExifIntTag(image, Orientation)
metadata := ImageMetadata{
Size: size,
Channels: int(image.Bands),
Orientation: orientation,
Alpha: vipsHasAlpha(image),
Profile: vipsHasProfile(image),
Space: vipsSpace(image),
Type: ImageTypeName(imageType),
EXIF: EXIF{
Make: vipsExifStringTag(image, Make),
Model: vipsExifStringTag(image, Model),
Orientation: orientation,
XResolution: vipsExifStringTag(image, XResolution),
YResolution: vipsExifStringTag(image, YResolution),
ResolutionUnit: vipsExifIntTag(image, ResolutionUnit),
Software: vipsExifStringTag(image, Software),
Datetime: vipsExifStringTag(image, Datetime),
YCbCrPositioning: vipsExifIntTag(image, YCbCrPositioning),
Compression: vipsExifIntTag(image, Compression),
ExposureTime: vipsExifStringTag(image, ExposureTime),
FNumber: vipsExifStringTag(image, FNumber),
ExposureProgram: vipsExifIntTag(image, ExposureProgram),
ISOSpeedRatings: vipsExifIntTag(image, ISOSpeedRatings),
ExifVersion: vipsExifStringTag(image, ExifVersion),
DateTimeOriginal: vipsExifStringTag(image, DateTimeOriginal),
DateTimeDigitized: vipsExifStringTag(image, DateTimeDigitized),
ComponentsConfiguration: vipsExifStringTag(image, ComponentsConfiguration),
ShutterSpeedValue: vipsExifStringTag(image, ShutterSpeedValue),
ApertureValue: vipsExifStringTag(image, ApertureValue),
BrightnessValue: vipsExifStringTag(image, BrightnessValue),
ExposureBiasValue: vipsExifStringTag(image, ExposureBiasValue),
MeteringMode: vipsExifIntTag(image, MeteringMode),
Flash: vipsExifIntTag(image, Flash),
FocalLength: vipsExifStringTag(image, FocalLength),
SubjectArea: vipsExifStringTag(image, SubjectArea),
MakerNote: vipsExifStringTag(image, MakerNote),
SubSecTimeOriginal: vipsExifStringTag(image, SubSecTimeOriginal),
SubSecTimeDigitized: vipsExifStringTag(image, SubSecTimeDigitized),
ColorSpace: vipsExifIntTag(image, ColorSpace),
PixelXDimension: vipsExifIntTag(image, PixelXDimension),
PixelYDimension: vipsExifIntTag(image, PixelYDimension),
SensingMethod: vipsExifIntTag(image, SensingMethod),
SceneType: vipsExifStringTag(image, SceneType),
ExposureMode: vipsExifIntTag(image, ExposureMode),
WhiteBalance: vipsExifIntTag(image, WhiteBalance),
FocalLengthIn35mmFilm: vipsExifIntTag(image, FocalLengthIn35mmFilm),
SceneCaptureType: vipsExifIntTag(image, SceneCaptureType),
GPSLatitudeRef: vipsExifStringTag(image, GPSLatitudeRef),
GPSLatitude: vipsExifStringTag(image, GPSLatitude),
GPSLongitudeRef: vipsExifStringTag(image, GPSLongitudeRef),
GPSLongitude: vipsExifStringTag(image, GPSLongitude),
GPSAltitudeRef: vipsExifStringTag(image, GPSAltitudeRef),
GPSAltitude: vipsExifStringTag(image, GPSAltitude),
GPSSpeedRef: vipsExifStringTag(image, GPSSpeedRef),
GPSSpeed: vipsExifStringTag(image, GPSSpeed),
GPSImgDirectionRef: vipsExifStringTag(image, GPSImgDirectionRef),
GPSImgDirection: vipsExifStringTag(image, GPSImgDirection),
GPSDestBearingRef: vipsExifStringTag(image, GPSDestBearingRef),
GPSDestBearing: vipsExifStringTag(image, GPSDestBearing),
GPSDateStamp: vipsExifStringTag(image, GPSDateStamp),
},
}
return metadata, nil
}