Go Dili İle Resim Boyutlandırma

package main
import (
	"fmt"
	"os"
	"path/filepath"
	"github.com/disintegration/imaging"
)
func main() {
	//fmt.Println("Enter Folder Path:")
	//var searchDir string
	//fmt.Scanln(&searchDir)
	fmt.Println("Enter Image Width:")
	var imgWidth int
	fmt.Scanln(&imgWidth)
	fmt.Println("Enter Image Height:")
	var imgHeight int
	fmt.Scanln(&imgHeight)
	var fileInfo os.FileInfo
	searchDir, _ := os.Getwd()
	fileList := []string{}
	err := filepath.Walk(searchDir, func(path string, f os.FileInfo, err error) error {
		fileList = append(fileList, path)
		return nil
	})
	if err != nil {
		fmt.Print(err)
	} else {
		for _, file := range fileList {
			fileInfo, err = os.Stat(file)
			if fileInfo.IsDir() {
				continue
			}
			fmt.Println(file)
			src, err := imaging.Open(file)
			if err != nil {
				continue
			}
			dstImage := imaging.Resize(src, imgWidth, imgHeight, imaging.Lanczos)
			var extension = filepath.Ext(file)
			var name = file[0 : len(file)-len(extension)]
			err = imaging.Save(dstImage, name+"_."+extension)
			if err != nil {
				fmt.Print("Save failed: %v", err)
			}
		}
	}
}


Uygulamamız, bir klasörün içerisindeki resimleri belirtilen genişlik ve yükseklik değerlerine göre toplu olarak boyutlandırmaktadır. Kendi ihtiyacıma göre hazırladığım için içerisinde çalıştırıldığı klasör yolunu otomatik olarak almakta ve bu klasördeki resimleri boyutlandırmaktadır. Uygulama go dili ile yaptığım ilk proje olduğu için hatalarım olabilir, kusura bakmayın.
Kodumuzda klasör ve dosya işlemleri için
“os”
“path/filepath”

Kütüphanelerini kullandık. “os” kütüphanesi dosya ve klasörler üzerinde kopyalama, taşıma, silme vb. gibi işlemler için kullanılırken, “path/filepath” kütüphanesini özellikle Walk metodu ile recursive olarak yani tüm alt klasörlere kadar inerek resimleri araması amacıyla kullanıyoruz.

fmt.Println("Enter Image Width:")
var imgWidth int
fmt.Scanln(&imgWidth)
fmt.Println("Enter Image Height:")
var imgHeight int
fmt.Scanln(&imgHeight)

satırlarında Println ekrana yazdırma metodu ve Scanln ekrandan değer okuma metodlarını kullanarak resim boyutlandırma işleminde kullanılacak genişlik ve yükseklik değerlerini kullanıcıdan istiyoruz.

var fileInfo os.FileInfo	
searchDir, _ := os.Getwd()
fileList := []string{}
err := filepath.Walk(searchDir, func(path string, f os.FileInfo, err error) error {
	fileList = append(fileList, path)
	return nil
})

Satırlarında klasör içerisindeki resim dosyalarını listelemek için gerekli işlemleri gerçekleştiriyoruz. Öncelikle os.Getwd() metodu ile uygulamamızın çalıştığı klasör yolunu elde ederek searchDir değişkenine aktarıyoruz. Böylelikle kodumuz, çalıştırıldığı klasördeki dosyalar üzerinde işlem gerçekleştirecektir.
Daha sonra filepath.Walk() metoduyla recursive olarak içerisinde bulunulan klasör ve alt klasörleri elde ediyoruz. Filepath.Walk() metodunun kullanım şekli aşağıdaki gibidir:

func Walk(root string, walkFn WalkFunc) error

root parametresi kök dizini belirtirken, walkFn parametresi klasörler arasında gezinirken çağrılacak fonksiyonu belirtir.
Foksiyonumuzu ise

type WalkFunc func(path string, info os.FileInfo, err error) error

Şeklinde tanımlıyoruz. path parametresi klasör yolunu, info parametresi belirtilen yol için os.FileInfo bilgilerini verir.
os.FileInfo bize aşağıdaki bilgileri geriye döndürür.
Name() string // Dosya adı bilgisini içerir
Size() int64 // Dosya boyutu bilgisini içerir
Mode() FileMode // Dosya modu bilgisini içerir.
ModTime() time.Time // Son düzenleme zamanı bilgisini içerir.
IsDir() bool // Belirtilen yolun klasör olup olmadığı bilgisini verir. Mode().IsDir() ile aynı görevi yapar.
Konunun daha iyi anlaşılması için Os.FileInfo ile belirtilen yolun dosya mı klasör mü olduğu bilgisini veren bir örnek verelim.

package main
import (
	"fmt"
	"os"
)
func main() {
	fi, err := os.Stat("klasör yolu")
	if err != nil {
		fmt.Println(err)
		return
	}
	switch mode := fi.Mode(); {
		case mode.IsDir():
			fmt.Println("directory")
		case mode.IsRegular():
			fmt.Println("file")
	}
}

Kodumuzda os.Stat ile belirtilen yolla ilgili dosya ya da klasör bilgisini os.FileInfo türünden elde ettik. fileInfo.Mode arayüzünü kullanarak IsDir() ve IsRegular() metodları ile belirtilen yolun dosya ya da klasör olup olmadığı bilgisini elde ettik.

Kodumuzu açıklamaya kaldığımız yerden devam edelim. Kodumuzda

fileList = append(fileList, path)

satırında okunan dosya yolu bilgisini fileList isimli dizi değişkene aktarıyoruz.

for _, file := range fileList {

satırında fileList dizisi içerisindeki dosya isimlerini okuyacak bir for döngü kuruyoruz. Döngü içerisinde

fileInfo, err = os.Stat(file)

satırında belirtilen yolla ilgili dosya ya da klasör bilgisini elde ettik.

if fileInfo.IsDir() {
    continue
}

Satırında eğer belirtilen yol bir klasör ise continue metodu ile döngünün sıradaki adımının atlanarak, döngünün bir sonraki adımdan devam etmesi sağlanır.

src, err := imaging.Open(file)

satırında eğer belirtilen yol bir dosya ise, dosyanın bir imaj dosyası olarak açılarak src değişkenine aktarılması sağlanır.

dstImage := imaging.Resize(src, imgWidth, imgHeight, imaging.Lanczos)

satırında imaging.Resize() metodu ile resim dosyasının yeniden boyutlandırılması sağlanır.
imaging.Resize metodu aşağıdaki gibi kullanılır.

imaging.Resize(kaynak resim dosyası, genişlik değeri, yükseklik değeri, resim filtresi)

resim filtresi parametresinde şu seçenekler kullanılabilir: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine.
Kodumuzda kullandığımız Lanczos filtresi fotoğraflar için keskin sonuçlar veren yüksek kaliteli bir filtredir. Filtrelerle ilgili daha detaylı bilgi için imaging kütüphanesini https://github.com/disintegration/imaging adresinden inceleyebilirsiniz.

Sonraki aşamada resim dosyalarını yeniden isimlendireceğiz. Öncelikle

var extension = filepath.Ext(file)

satırında filepath.Ext() metodu ile belirtilen imaj dosyasının uzantısını elde ediyoruz.

var name = file[0 : len(file)-len(extension)]

satırında ise dosya ismi bilgisini elde ediyoruz. Bunun için dosya ismi ve uzantısı bilgisinden (len(file)), dosya uzantısını (len(extension)) çıkarıyoruz.

err = imaging.Save(dstImage, name+"_."+extension)

Satırında imaging.Save metoduyla resim dosyasını “dosyaadı_.uzantı” şeklinde kaydediyoruz.

Kaynak kodlara https://github.com/volkanaktas/Image-Resizer adresinden erişebilirsiniz.

Go Dili İle Resim Boyutlandırma” için 2 yorum

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir