fix(wallet)_: Fix handling of remote image URLs in image processing
- Addressed the issue where remote image URLs failed to be processed due to local file handling restrictions. - Introduced `FetchAndStoreRemoteImage` to download and save remote images to a temporary file, enabling compatibility with existing processing functions. - Split the main image handling logic into smaller functions (`OpenAndDecodeImage`, `AdjustImage`) for better modularity and maintainability. - Updated `OpenAndAdjustImage` to use these new functions, ensuring a streamlined flow for both local and remote images. - Added cleanup steps for temporary files to prevent resource leaks. resolves: #15691
This commit is contained in:
parent
130c995b92
commit
7ed92531c2
|
@ -3,9 +3,13 @@ package images
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -16,48 +20,92 @@ const (
|
|||
|
||||
var DefaultBounds = FileSizeLimits{Ideal: idealTargetImageSize, Max: resizeTargetImageSize}
|
||||
|
||||
func OpenAndAdjustImage(inputImage CroppedImage, crop bool) ([]byte, error) {
|
||||
file, err := os.Open(inputImage.ImagePath)
|
||||
func FetchAndStoreRemoteImage(url string) (string, error) {
|
||||
resp, err := http.Get(url) //nolint
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", fmt.Errorf("error fetching image from URL: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("bad status code: %s", resp.Status)
|
||||
}
|
||||
|
||||
tempFile, err := ioutil.TempFile("", "image-*")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error creating a temporary file: %w", err)
|
||||
}
|
||||
defer tempFile.Close()
|
||||
|
||||
_, err = io.Copy(tempFile, resp.Body)
|
||||
if err != nil {
|
||||
os.Remove(tempFile.Name()) // Ensure temporary file is deleted on error
|
||||
return "", fmt.Errorf("error writing image to temp file: %w", err)
|
||||
}
|
||||
|
||||
return tempFile.Name(), nil
|
||||
}
|
||||
|
||||
func OpenAndDecodeImage(imagePath string) (image.Image, error) {
|
||||
file, err := os.Open(imagePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error opening image file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
payload, err := ioutil.ReadAll(file)
|
||||
img, err := Decode(imagePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("error decoding image: %w", err)
|
||||
}
|
||||
|
||||
img, err := Decode(inputImage.ImagePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return img, nil
|
||||
}
|
||||
|
||||
func AdjustImage(img image.Image, crop bool, inputImage CroppedImage) ([]byte, error) {
|
||||
if crop {
|
||||
cropRect := image.Rectangle{
|
||||
Min: image.Point{X: inputImage.X, Y: inputImage.Y},
|
||||
Max: image.Point{X: inputImage.X + inputImage.Width, Y: inputImage.Y + inputImage.Height},
|
||||
}
|
||||
var err error
|
||||
img, err = Crop(img, cropRect)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("error cropping image: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
bb := bytes.NewBuffer([]byte{})
|
||||
err = CompressToFileLimits(bb, img, DefaultBounds)
|
||||
err := CompressToFileLimits(bb, img, DefaultBounds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We keep the smallest one
|
||||
if len(payload) > len(bb.Bytes()) {
|
||||
payload = bb.Bytes()
|
||||
return nil, fmt.Errorf("error compressing image: %w", err)
|
||||
}
|
||||
|
||||
payload := bb.Bytes()
|
||||
if len(payload) > maxChatMessageImageSize {
|
||||
return nil, errors.New("image too large")
|
||||
}
|
||||
|
||||
return payload, nil
|
||||
}
|
||||
func OpenAndAdjustImage(inputImage CroppedImage, crop bool) ([]byte, error) {
|
||||
var imgPath string = inputImage.ImagePath
|
||||
var err error
|
||||
|
||||
// Check if the image is from a remote source
|
||||
if strings.HasPrefix(inputImage.ImagePath, "http://") || strings.HasPrefix(inputImage.ImagePath, "https://") {
|
||||
imgPath, err = FetchAndStoreRemoteImage(inputImage.ImagePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer os.Remove(imgPath) // Clean up the temporary file
|
||||
}
|
||||
|
||||
// Decode the image
|
||||
img, err := OpenAndDecodeImage(imgPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Adjust (crop and compress) the image
|
||||
return AdjustImage(img, crop, inputImage)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue