github.com/vulppine/fotoDen@v0.3.0/generator/image.go (about)

     1  package generator
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  	"strconv"
     7  
     8  	"github.com/h2non/bimg"
     9  )
    10  
    11  // IsolateImages isolates images in an array.
    12  //
    13  // Checks all image files at O(n), if a file is not an image, removes it from the current slice.
    14  func IsolateImages(files []string) []string {
    15  	for i := 0; i < len(files); i++ {
    16  		image, err := bimg.Read(files[i])
    17  		if err != nil {
    18  			fmt.Println(err)
    19  		} else {
    20  			if bimg.DetermineImageType(image) == bimg.UNKNOWN {
    21  				verbose("File " + files[i] + " is not an image. Removing.")
    22  				files = RemoveItemFromStringArray(files, files[i]) // replace this with an append later
    23  				i--                                                // because now everything is shifted one backwards
    24  			}
    25  		}
    26  	}
    27  
    28  	return files
    29  }
    30  
    31  // ImageScale represents scaling options to be used by ResizeImage.
    32  // See ResizeImage for more information.
    33  type ImageScale struct {
    34  	MaxHeight    int
    35  	MaxWidth     int
    36  	ScalePercent float64
    37  }
    38  
    39  // ResizeImage resizes a single image.
    40  //
    41  // You'll have to pass it a ImageScale object,
    42  // which contains values for either a scale percentage, or a max height/width.
    43  // In order of usage:
    44  // maxheight, maxwidth, scalepercent
    45  //
    46  // maxheight is first due to a restriction with CSS Flex and mixed height images,
    47  // maxwidth is second for the same thing, but with flex set to column mode,
    48  // scalepercent is final for when the first two don't apply.
    49  //
    50  // The function will output the image to the given directory, without changing the name.
    51  // It will return an error if the filename given already exists in the destination directory.
    52  func ResizeImage(file string, imageName string, scale ImageScale, dest string, imageFormat bimg.ImageType) error {
    53  	image, err := bimg.Read(file)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	imageType := bimg.DetermineImageType(image)
    59  	if imageType == bimg.UNKNOWN {
    60  		return fmt.Errorf("ResizeImage: Unknown file type. Skipping. Image: %s", imageName)
    61  	}
    62  
    63  	newImage, err := bimg.NewImage(image).Convert(imageFormat)
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	size, err := bimg.NewImage(image).Size()
    69  	width := float64(size.Width)
    70  	height := float64(size.Height)
    71  
    72  	switch {
    73  	case scale.MaxHeight != 0:
    74  		scale := float64(scale.MaxHeight) / height
    75  		width = width * scale
    76  		height = height * scale
    77  	case scale.MaxWidth != 0:
    78  		scale := float64(scale.MaxWidth) / width
    79  		width = width * scale
    80  		height = height * scale
    81  	case scale.ScalePercent != 0:
    82  		width = width * scale.ScalePercent
    83  		height = height * scale.ScalePercent
    84  	default:
    85  		return fmt.Errorf("ResizeImage: Image scaling undefined. Aborting. scale: " + fmt.Sprint(scale))
    86  	}
    87  
    88  	verbose("Resizing " + imageName + " to " + strconv.Itoa(int(width)) + "," + strconv.Itoa(int(height)) + " and attempting to place it in " + path.Join(dest, imageName))
    89  	newImage, err = bimg.NewImage(newImage).Resize(int(width), int(height))
    90  	if err != nil {
    91  		return err
    92  	}
    93  
    94  	destCheck, err := bimg.Read(path.Join(dest, imageName))
    95  	if destCheck != nil {
    96  		return err
    97  	}
    98  
    99  	bimg.Write(path.Join(dest, imageName), newImage)
   100  	return nil
   101  }
   102  
   103  // ImageMeta provides metadata such as name and description for an image file.
   104  // This is used by fotoDen on the web frontend to display custom per-image information.
   105  type ImageMeta struct {
   106  	ImageName string // The name of an image.
   107  	ImageDesc string // The description of an image.
   108  }
   109  
   110  // WriteImageMeta writes an ImageMeta struct to a file.
   111  //
   112  // Takes two arguments: a folder destination, and a name.
   113  // The name is automatically combined to create a [name].json file,
   114  // in order to ensure compatibility with fotoDen.
   115  // Writes the json file into the given folder.
   116  func (meta *ImageMeta) WriteImageMeta(folder string, name string) error {
   117  	err := WriteJSON(path.Join(folder, name+".json"), "multi", meta)
   118  	if err != nil {
   119  		return err
   120  	}
   121  
   122  	return nil
   123  }
   124  
   125  // MakeFolderThumbnail creates a thumbnail from a file into a destination directory.
   126  // This is only here to make fotoDen's command line tool look cleaner in code, and avoid importing more than needed.
   127  func MakeFolderThumbnail(file string, directory string) error {
   128  	err := ResizeImage(file, "thumb.jpg", ImageScale{MaxHeight: 500}, directory, bimg.JPEG)
   129  	if err != nil {
   130  		return err
   131  	}
   132  
   133  	return nil
   134  }