[Go] Create a CLI command to change the extension of the image

Introduction

Before this, I participated in the study room of ** Gopher Dojo ** and searched for the Gopher Dojo issues that I had been interested in for a long time on github. , (Is it okay to do it ...?) I practiced.

The first issue was ** changing the extension of the image **. I want to output it for the time being, so I will write various things here. Also, from the package used, I will explain a little about flag, ʻos, path / filepath, ʻimage.

environment

# go version
go version go1.15.2 linux/amd64

# tree
.
|- conversion
|       |- conversion.go
|- go.mod
|- main.go

Actual code

For the time being, the repository is here

main.go


package main

import (
	"cvs/conversion"
	"flag"
	"fmt"
	"os"
	"path/filepath"
)

var (
	extension string
	imagepath string
	dirpath   string
)

func main() {

	flag.StringVar(&extension, "e", "jpeg", "Specifying the extension")
	flag.StringVar(&imagepath, "f", "", "Specify the path of the file to be converted")
	flag.StringVar(&dirpath, "d", "", "Specifying the file name after conversion")
	flag.Parse()
	err := conversion.ExtensionCheck(extension)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}

	err = conversion.FilepathCheck(imagepath)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}

	err = conversion.DirpathCheck(dirpath)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}

	f := filepath.Ext(imagepath)
	err = conversion.FileExtCheck(f)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}

	fmt.Println("Converting ...")

	err = conversion.FileExtension(extension, imagepath, dirpath)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}
}

conversion.go


/*
Conversion is a package for changing the extension of an image.
*/
package conversion

import (
	"errors"
	"fmt"
	"image"
	"image/gif"
	"image/jpeg"
	"image/png"
	"os"

	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
)

const (
	JPEG = "jpeg"
	JPG  = "jpg"
	GIF  = "gif"
	PNG  = "png"
)

// -Determines if the extension specified by e is supported.
func ExtensionCheck(ext string) error {
	switch ext {
	case JPEG, JPG, GIF, PNG:
		return nil
	default:
		return errors.New("Extension that cannot be specified" + ext)
	}
}

// -Determines if the file specified by f exists.
func FilepathCheck(imagepath string) error {
	switch imagepath {
	case "":
		return errors.New("File is not specified")
	default:
		if f, err := os.Stat(imagepath); os.IsNotExist(err) || f.IsDir() {
			return errors.New("File does not exist" + imagepath)
		} else {
			return nil
		}
	}
}

func DirpathCheck(dirpath string) error {
	switch dirpath {
	case "":
		return errors.New("The converted file name is not specified")
	default:
		return nil
	}
}

func FileExtCheck(imagepath string) error {
	switch imagepath {
	case "." + JPEG, "." + JPG, "." + GIF, "." + PNG:
		return nil
	default:
		return errors.New("The specified file is not supported. :" + imagepath)
	}
}

func FileExtension(extension string, imagepath string, dirpath string) error {
	exFile, err := os.Open(imagepath)
	defer exFile.Close()
	if err != nil {
		return errors.New("os.Create failed")
	}

	output, err := os.Create(dirpath)
	defer output.Close()
	if err != nil {
		return errors.New("output failure")
	}

	img, _, Err := image.Decode(exFile)
	if Err != nil {
		return errors.New("Decode failure")
	}

	switch extension {
	case JPEG, JPG:
		err = jpeg.Encode(output, img, nil)
		if err != nil {
			return errors.New("Encode failure")
		}
		fmt.Println("Successful conversion")
		return nil
	case GIF:
		err = gif.Encode(output, img, nil)
		if err != nil {
			return errors.New("Encode failure")
		}
		fmt.Println("Successful conversion")
		return nil
	case PNG:
		err = png.Encode(output, img)
		if err != nil {
			return errors.New("Encode failure")
		}
		fmt.Println("Successful conversion")
		return nil
	}
	return nil
}

go.mod


module cvs

go 1.15

For the time being, I made it work properly while making error handling appropriate.

Code commentary

As the theme of this code, --Use go mod --Use go doc --Separate packages

I decided that. For the time being, the reason is

  1. go mod makes package splitting easier to use
  2. Increase availability by creating documentation with go doc There are these two. But this time it's a pass.

I will write about the package used this time.

If you raise the package used for the CLI command to change the extension of the image,

  1. flag
  2. os
  3. path/filepath
  4. image

there is. I will explain each of them.

flag Documentation Used to get arguments as an option from the command line

Implemented code(main.go)


var (
	extension string
	imagepath string
	dirpath   string
)
func main() {

	flag.StringVar(&extension, "e", "jpeg", "Specifying the extension")
 // -e "String" で、Stringを取得する/By default"jpeg"Is specified
	flag.StringVar(&imagepath, "f", "", "Specify the path of the file to be converted")
	flag.StringVar(&dirpath, "d", "", "Specifying the file name after conversion")
	flag.Parse() 
//Without Parse, it will not be parsed into a variable

~~~ omitted

How to write


flag.StringVar(&Variable name, "Optional symbol", "Default value","Description of this option")

You can get other than getting the character string (should)

os Documentation This time, I used it to save the image to see if the specified image really exists.

Implemented code(conversion.go)


func FilepathCheck(imagepath string) error {
	switch imagepath {
	case "":
		return errors.New("File is not specified")
	default:
		if f, err := os.Stat(imagepath); os.IsNotExist(err) || f.IsDir() {
			return errors.New("File does not exist" + imagepath)
		} else {
			return nil
		}
	}
}

//-It is a function that determines whether the file specified by f exists.

This guy can do pretty much anything.

path/filepath Documentation I'm getting the arguments of the function I introduced earlier. I'm getting the file path from string.

Implemented code(main.go)


f := filepath.Ext(imagepath)
err = conversion.FileExtCheck(f)
//Check if the imagepath really exists

image Documentation The image processing system can be done with this guy.

Implemented code(conversion.go)


img, _, Err := image.Decode(exFile)
if Err != nil {
	return errors.New("Decode failure")
}
//Image decoding process

switch extension {
case JPEG, JPG:
	err = jpeg.Encode(output, img, nil)
	if err != nil {
		return errors.New("Encode failure")
	}
	fmt.Println("Successful conversion")
	return nil
case GIF:
	err = gif.Encode(output, img, nil)
	if err != nil {
		return errors.New("Encode failure")
	}
	fmt.Println("Successful conversion")
	return nil
case PNG:
	err = png.Encode(output, img)
	if err != nil {
		return errors.New("Encode failure")
	}
	fmt.Println("Successful conversion")
	return nil
}
//Encode according to the converted extension

It seems that image processing can be done almost only with this guy

Summary

When I actually run it, ...

# go build -o cvs
# ./cvs -e png -f sample.jpeg -d sample.png
Converting ...
Successful conversion

You can convert it like that.

By the way, even if you write it appropriately instead of .png after -d, the extension is converted properly.

If you convert it with a browser, there is no such thing as a strange script, and it is safe.

It was challenging and fun, so I wonder if I should make another command.

Then.

Recommended Posts

[Go] Create a CLI command to change the extension of the image
Create a function to get the contents of the database in Go
Create a command to get the work log
How to change the generated image of GAN to a high quality one to your liking
How to output the output result of the Linux man command to a file
A command to easily check the speed of the network on the console
Script to change the description of fasta
Notice the completion of a time-consuming command
Various methods to numerically create the inverse function of a certain function Introduction
[Linux] Command to get a list of commands executed in the past
How to create a wrapper that preserves the signature of the function to wrap
How to calculate the volatility of a brand
Create a command to encode / decode Splunk base64
I tried to correct the keystone of the image
Change the decimal point of logging from, to.
Use click to create a sub-sub command --netsted sub-sub command -
Try to create a new command on linux
How to create a shortcut command for LINUX
How to pass the execution result of a shell command in a list in Python
Zip-compress any file with the [shell] command to create a file and delete the original file.
I made an appdo command to execute a command in the context of the app
A memorandum of how to execute the! Sudo magic command in Jupyter Notebook
Change the data frame of pandas purchase data (id x product) to a dictionary
[AWS Lambda] Create a deployment package using the Docker image of Amazon Linux
I tried to create a model with the sample of Amazon SageMaker Autopilot
[Python3] Code that can be used when you want to change the extension of an image at once
Read the Python-Markdown source: How to create a parser
How to create an article from the command line
Create a function to visualize / evaluate the clustering result
How to write a GUI using the maya command
Various methods to numerically create the inverse function of a certain function Part 1 Polynomial regression
A memo to visually understand the axis of pandas.Panel
Try to create a battle record table with matplotlib from the data of "Schedule-kun"
How to create a submenu with the [Blender] plugin
[Go] How to create a custom error for Sentry
Steps to calculate the likelihood of a normal distribution
[Django] Change the Default IP address of the runserver command
I made a command to markdown the table clipboard
Create a shape on the trajectory of an object
Python Note: The mystery of assigning a variable to a variable
Create a web page that runs a model that increases the resolution of the image using gradio, which makes it easy to create a web screen
[Golang] Command to check the supported GOOS and GOARCH in a list (Check the supported platforms of the build)
I tried to create a Python script to get the value of a cell in Microsoft Excel
I made a function to crop the image of python openCV, so please use it.
Does TensorFlow change the image of deep learning? What I thought after touching a little
[Python] How to create a table from list (basic operation of table creation / change of matrix name)
Create a 2D array by adding a row to the end of an empty array with numpy
How to pass the execution result of a shell command in a list in Python (non-blocking version)
I tried to find the entropy of the image with python
[Python] Change the Cache-Control of the object uploaded to Cloud Storage
[Go language] Try to create a uselessly multi-threaded line counter
[Ubuntu] How to delete the entire contents of a directory
Get UNIXTIME at the beginning of today with a command
Change the standard output destination to a file in Python
An introduction to object orientation-let's change the internal state of an object
[Command] Command to get a list of files containing double-byte characters
Probably the easiest way to create a pdf with Python3
I made a function to check the model of DCGAN
I made a dot picture of the image of Irasutoya. (part1)
To write a test in Go, first design the interface
How to find the scaling factor of a biorthogonal wavelet