github.com/openimsdk/tools@v0.0.49/s3/minio/image.go (about)

     1  // Copyright © 2023 OpenIM. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package minio
    16  
    17  import (
    18  	"image"
    19  	_ "image/gif"
    20  	_ "image/jpeg"
    21  	_ "image/png"
    22  	"io"
    23  
    24  	_ "golang.org/x/image/bmp"
    25  	_ "golang.org/x/image/tiff"
    26  	_ "golang.org/x/image/webp"
    27  )
    28  
    29  const (
    30  	formatPng  = "png"
    31  	formatJpeg = "jpeg"
    32  	formatJpg  = "jpg"
    33  	formatGif  = "gif"
    34  	formatWebP = "webp"
    35  	formatTiff = "tiff"
    36  	formatBmp  = "bmp"
    37  
    38  	formatHeic = "heic"
    39  	formatHeif = "heif"
    40  	formatAvif = "avif"
    41  )
    42  
    43  func ImageStat(reader io.Reader) (image.Image, string, error) {
    44  	return image.Decode(reader)
    45  }
    46  
    47  func ImageWidthHeight(img image.Image) (int, int) {
    48  	bounds := img.Bounds().Max
    49  	return bounds.X, bounds.Y
    50  }
    51  
    52  func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
    53  	bounds := img.Bounds()
    54  	imgWidth := bounds.Max.X
    55  	imgHeight := bounds.Max.Y
    56  
    57  	// Calculating scaling
    58  	scaleWidth := float64(maxWidth) / float64(imgWidth)
    59  	scaleHeight := float64(maxHeight) / float64(imgHeight)
    60  
    61  	// If both are 0, then no scaling is done and the original image is returned
    62  	if maxWidth == 0 && maxHeight == 0 {
    63  		return img
    64  	}
    65  
    66  	// If both width and height are greater than 0, select a smaller zoom ratio to maintain the aspect ratio
    67  	if maxWidth > 0 && maxHeight > 0 {
    68  		scale := scaleWidth
    69  		if scaleHeight < scaleWidth {
    70  			scale = scaleHeight
    71  		}
    72  
    73  		// Calculate Thumbnail Size
    74  		thumbnailWidth := int(float64(imgWidth) * scale)
    75  		thumbnailHeight := int(float64(imgHeight) * scale)
    76  
    77  		// Thumbnails are generated using the Resample method of the "image" library.
    78  		thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
    79  		for y := 0; y < thumbnailHeight; y++ {
    80  			for x := 0; x < thumbnailWidth; x++ {
    81  				srcX := int(float64(x) / scale)
    82  				srcY := int(float64(y) / scale)
    83  				thumbnail.Set(x, y, img.At(srcX, srcY))
    84  			}
    85  		}
    86  
    87  		return thumbnail
    88  	}
    89  
    90  	// If only width or height is specified, thumbnails are generated based on the maximum not to exceed rule
    91  	if maxWidth > 0 {
    92  		thumbnailWidth := maxWidth
    93  		thumbnailHeight := int(float64(imgHeight) * scaleWidth)
    94  
    95  		// Thumbnails are generated using the Resample method of the "image" library.
    96  		thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
    97  		for y := 0; y < thumbnailHeight; y++ {
    98  			for x := 0; x < thumbnailWidth; x++ {
    99  				srcX := int(float64(x) / scaleWidth)
   100  				srcY := int(float64(y) / scaleWidth)
   101  				thumbnail.Set(x, y, img.At(srcX, srcY))
   102  			}
   103  		}
   104  
   105  		return thumbnail
   106  	}
   107  
   108  	if maxHeight > 0 {
   109  		thumbnailWidth := int(float64(imgWidth) * scaleHeight)
   110  		thumbnailHeight := maxHeight
   111  
   112  		// Thumbnails are generated using the Resample method of the "image" library.
   113  		thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
   114  		for y := 0; y < thumbnailHeight; y++ {
   115  			for x := 0; x < thumbnailWidth; x++ {
   116  				srcX := int(float64(x) / scaleHeight)
   117  				srcY := int(float64(y) / scaleHeight)
   118  				thumbnail.Set(x, y, img.At(srcX, srcY))
   119  			}
   120  		}
   121  
   122  		return thumbnail
   123  	}
   124  
   125  	// By default, the original image is returned
   126  	return img
   127  }
   128  
   129  func getThumbnailSize(img image.Image) (thumbnailWidth, thumbnailHeight int) {
   130  	bounds := img.Bounds()
   131  	imgWidth := bounds.Max.X
   132  	imgHeight := bounds.Max.Y
   133  
   134  	if imgWidth < 640 {
   135  		thumbnailWidth = imgWidth
   136  	} else {
   137  		thumbnailWidth = 640
   138  	}
   139  	if imgHeight < 640 {
   140  		thumbnailHeight = imgHeight
   141  	} else {
   142  		thumbnailHeight = 640
   143  	}
   144  	return thumbnailWidth, thumbnailHeight
   145  }