package imgedit import ( "context" "encoding/json" "fmt" "image" "os" "path/filepath" "github.com/disintegration/imaging" "lmika.dev/lmika/weiro/models" ) func (s *Service) reprocess(ctx context.Context, session models.ImageEditSession) (imageSource, error) { var img imageSource for _, p := range session.Processors { // Check if there's currently a cached image of this processor cachedImageFile := filepath.Join(s.scratchDir, session.GUID, fmt.Sprintf("%v.%v", p.VersionID, session.ImageExt)) if s, err := os.Stat(cachedImageFile); err == nil && !s.IsDir() { img = fileImageSource(cachedImageFile) continue } // Need to process the image var srcImg image.Image if img != nil { var err error srcImg, err = img.image() if err != nil { return nil, err } } resImg, err := s.processImage(ctx, srcImg, p) if err != nil { return nil, err } // Cache the processed image if err := imaging.Save(resImg, cachedImageFile); err != nil { return nil, err } img = imageImageSource{resImg} } return img, nil } func (s *Service) processImage(ctx context.Context, srcImg image.Image, processor models.ImageEditProcessor) (image.Image, error) { switch processor.Type { case "copy-upload": var p models.CopyUploadProps if err := json.Unmarshal(processor.Props, &p); err != nil { return nil, err } _, rc, err := s.uploadService.OpenUpload(ctx, p.UploadID) if err != nil { return nil, err } f, err := rc() if err != nil { return nil, err } defer f.Close() return imaging.Decode(f) } return nil, fmt.Errorf("unknown processor type: %v", processor.Type) } type imageSource interface { image() (image.Image, error) } type fileImageSource string func (f fileImageSource) image() (image.Image, error) { return imaging.Open(string(f)) } type imageImageSource struct { img image.Image } func (i imageImageSource) image() (image.Image, error) { return i.img, nil }