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 }