Skip to content

msvens/mimage

Repository files navigation

codecov Go Report Card GoDoc

Overiew

mimage is a native go package for handling image meta information (exif, iptc, xmp) as well as some basic image manipulation (resizing, thumbnail creation, etc)

mimage is used by mphotos and we welcome others to try it out.

Installation

Installing mimage is easy as it only has go native dependencies.

go get -u github.com/msvens/mimage

Next include

import "github.com/msvens/mimage/metadata"

if you want to access and edit image metadata, or

import "github.com/msvens/mimage/img"

if you want to manipulate the actual image (crop,resize,thumbnails)

Usage

mimage has 3 main use cases: reading and writing metadata (exif, iptc, xmp) and "resizing" images.

Note: For now this package assumes jpeg images and will not work with other formats

Accessing Metadata

In its simplest form you instantiate a new MetaData struct from an image file or byte slice. This will parse the file and creat the corresponding IPTC, XMP and Exif Metadata as well as a summary with the most "frequently" used fields

md, err := NewMetaDataFromFile("../assets/leica.jpg")
if err != nil {
	fmt.Printf("Could not open file: %v\n", err)
	return
}
fmt.Printf("Make: %s, Model: %s\n", md.Summary().CameraMake, md.Summary().CameraModel)

You can always retrieve any metadata by scan that specific field from either IPTC, Xmp or Exif respectively.

cameraMake := ""
err = md.Exif().ScanIfdRoot(IFD_Make, &cameraMake)
if err != nil {
	fmt.Printf("Could not scan ifd tag: %v\n", err)
	return
}
fmt.Printf("Make: %s\n", cameraMake)

Editing Metadata

One can also edit (or add) metadata to an image. All known IPTC,Exif,and Xmp tags can be edited - much in the same why as you read those fields. There are conveniance methods to edit image titles and keywords (will set the fields in all relevant metadata sections) as those are typically not generated by your camera/image software

je, err := NewJpegEditorFile("../assets/leica.jpg")
if err != nil {
	fmt.Printf("Could not retrieve editor for file: %v\n", err)
	return
}
err = je.SetTitle("some new title")
if err != nil {
	fmt.Printf("Could not set title: %v\n", err)
	return
}
md, err := je.MetaData()
if err != nil {
	fmt.Printf("Could not get metadata: %v\n", err)
}
fmt.Printf("New Title: %v\n",md.Summary().Title)

In order to persist your editing you need to call any of these methods on your editor

je.MetaData() //Calls je.Bytes() then instantiates a new MetaData struct
je.Bytes() //Get []byte of the entire image
je.WriteFile(someFile) //Calls je.Bytes() then writes to someFile

Copy and Manipulating Images

The second function of image is to manipulate/transform images - typically to create thumbnails, portrait, landscape and other scaled versions of your original image. These copy functions will also respect and copy and original image metadata information - which the standard jpeg writers dont do.

The package "github.com/msvens/mimage/img" exposes one function

func TransformFile(source string, destinations map[string]Options) error 

In the follwoing example we use TransformFile to create a number of versions of our sourceImage.

sourceImg := "../assets/leica.jpg"
homeDir, _ := os.UserHomeDir()
sourceDir := path.Join(homeDir,"transform")
_ = os.Mkdir(sourceDir, 0755)

//for all but the thumb we are copying the original meta information
thumb := NewOptions(ResizeAndCrop, 400, 400, false)
landscape := NewOptions(ResizeAndCrop, 1200, 628, true)
square := NewOptions(ResizeAndCrop, 1200, 1200, true)
portrait := NewOptions(ResizeAndCrop, 1080, 1350, true)
resize := NewOptions(Resize, 1200, 0, true)

destImgs := map[string]Options{
	path.Join(sourceDir,"thumb.jpg"): thumb,
	path.Join(sourceDir, "landscape.jpg"): landscape,
	path.Join(sourceDir, "square.jpg"): square,
	path.Join(sourceDir, "portrait.jpg"): portrait,
	path.Join(sourceDir, "resize.jpg"): resize,
}

_ = TransformFile(sourceImg, destImgs)

Note that in a real situation you would handle the errors that we are now just skipping

Motivation

mphotos has relied on two libraries/tools for image manipulation and meta data extraction: bimg and exiftool. Both of these are excellent tools but made the compile/deployment process more complicated as bimg relies on libvips and exiftool is an external program that needs to be installed. In effect making mphotos slighly less portable.

mimage seeks to remedy this by offering similar functionality using only go native code

Releases

Todo

  • Add finer grained control over editing (only accept allowed values, etc)
  • Other image formats

Thanks

A big thanks to

  • exif-go for go native support of parsing and editing exif data
  • go-xmp for go native support of reading and editing XMP information
  • Imaging for go native support of image manipulation
  • exiftool for providing the sources of all exif and iptc tag information

About

Image manipulation and metadata tool

Resources

License

Stars

Watchers

Forks

Packages

No packages published