package openai import ( "bufio" "fmt" "image" "image/jpeg" "image/png" "io" "mime/multipart" "os" ) type ImageGenerationRequestBody struct { Prompt string `json:"prompt"` N int `json:"n"` Size string `json:"size"` ResponseFormat string `json:"response_format"` } type ImageResponseBody struct { Created int64 `json:"created"` Data []struct { Base64Json string `json:"b64_json"` } `json:"data"` } type ImageVariantRequestBody struct { Image string `json:"image"` N int `json:"n"` Size string `json:"size"` ResponseFormat string `json:"response_format"` } func (gpt *ChatGPT) GenerateImage(prompt string, size string, n int) ([]string, error) { requestBody := ImageGenerationRequestBody{ Prompt: prompt, N: n, Size: size, ResponseFormat: "b64_json", } imageResponseBody := &ImageResponseBody{} err := gpt.sendRequestWithBodyType(gpt.ApiUrl+"/v1/images/generations", "POST", jsonBody, requestBody, imageResponseBody) if err != nil { return nil, err } var b64Pool []string for _, data := range imageResponseBody.Data { b64Pool = append(b64Pool, data.Base64Json) } return b64Pool, nil } func (gpt *ChatGPT) GenerateOneImage(prompt string, size string) (string, error) { b64s, err := gpt.GenerateImage(prompt, size, 1) if err != nil { return "", err } return b64s[0], nil } func (gpt *ChatGPT) GenerateOneImageWithDefaultSize( prompt string) (string, error) { return gpt.GenerateOneImage(prompt, "512x512") } func (gpt *ChatGPT) GenerateImageVariation(images string, size string, n int) ([]string, error) { requestBody := ImageVariantRequestBody{ Image: images, N: n, Size: size, ResponseFormat: "b64_json", } imageResponseBody := &ImageResponseBody{} err := gpt.sendRequestWithBodyType(gpt.ApiUrl+"/v1/images/variations", "POST", formPictureDataBody, requestBody, imageResponseBody) if err != nil { return nil, err } var b64Pool []string for _, data := range imageResponseBody.Data { b64Pool = append(b64Pool, data.Base64Json) } return b64Pool, nil } func (gpt *ChatGPT) GenerateOneImageVariation(images string, size string) (string, error) { b64s, err := gpt.GenerateImageVariation(images, size, 1) if err != nil { return "", err } return b64s[0], nil } func pictureMultipartForm(request ImageVariantRequestBody, w *multipart.Writer) error { f, err := os.Open(request.Image) if err != nil { return fmt.Errorf("opening audio file: %w", err) } fw, err := w.CreateFormFile("image", f.Name()) if err != nil { return fmt.Errorf("creating form file: %w", err) } if _, err = io.Copy(fw, f); err != nil { return fmt.Errorf("reading from opened audio file: %w", err) } err = w.WriteField("size", request.Size) if err != nil { return fmt.Errorf("writing size: %w", err) } err = w.WriteField("n", fmt.Sprintf("%d", request.N)) if err != nil { return fmt.Errorf("writing n: %w", err) } err = w.WriteField("response_format", request.ResponseFormat) if err != nil { return fmt.Errorf("writing response_format: %w", err) } //err = w.WriteField("user", "user123456") //fw, err = w.CreateFormField("model") //if err != nil { // return fmt.Errorf("creating form field: %w", err) //} //modelName := bytes.NewReader([]byte(request.Model)) //if _, err = io.Copy(fw, modelName); err != nil { // return fmt.Errorf("writing model name: %w", err) //} //fmt.Printf("w.FormDataContentType(): %s ", w.FormDataContentType()) w.Close() return nil } func VerifyPngs(pngPaths []string) error { foundPng := false var expectedWidth, expectedHeight int for _, pngPath := range pngPaths { f, err := os.Open(pngPath) if err != nil { return fmt.Errorf("os.Open: %v", err) } fi, err := f.Stat() if err != nil { return fmt.Errorf("f.Stat: %v", err) } if fi.Size() > 4*1024*1024 { return fmt.Errorf("image size too large, "+ "must be under %d MB", 4) } image, err := png.Decode(f) if err != nil { return fmt.Errorf("image must be valid png, got error: %v", err) } width := image.Bounds().Dx() height := image.Bounds().Dy() if width != height { return fmt.Errorf("found non-square image with dimensions %dx%d", width, height) } if !foundPng { foundPng = true expectedWidth = width expectedHeight = height } else { if width != expectedWidth || height != expectedHeight { return fmt.Errorf("dimensions of all images must match, got both (%dx%d) and (%dx%d)", width, height, expectedWidth, expectedHeight) } } } return nil } func ConvertToRGBA(inputFilePath string, outputFilePath string) error { // 打开输入文件 inputFile, err := os.Open(inputFilePath) if err != nil { return fmt.Errorf("打开文件时出错:%w", err) } defer inputFile.Close() // 解码图像 img, _, err := image.Decode(inputFile) if err != nil { return fmt.Errorf("解码图像时出错:%w", err) } // 将图像转换为RGBA模式 rgba := image.NewRGBA(img.Bounds()) for x := 0; x < img.Bounds().Max.X; x++ { for y := 0; y < img.Bounds().Max.Y; y++ { rgba.Set(x, y, img.At(x, y)) } } // 创建输出文件 outputFile, err := os.Create(outputFilePath) if err != nil { return fmt.Errorf("创建输出文件时出错:%w", err) } defer outputFile.Close() // 编码图像为 PNG 格式并写入输出文件 if err := png.Encode(outputFile, rgba); err != nil { return fmt.Errorf("编码图像时出错:%w", err) } return nil } func ConvertJpegToPNG(jpgPath string) error { // Open the JPEG file for reading f, err := os.Open(jpgPath) if err != nil { return err } defer f.Close() // Check if the file is a JPEG image _, err = jpeg.Decode(f) if err != nil { // The file is not a JPEG image, no need to convert it return fmt.Errorf("file %s is not a JPEG image", jpgPath) } // Reset the file pointer to the beginning of the file _, err = f.Seek(0, 0) if err != nil { return err } // Create a new PNG file for writing pngPath := jpgPath[:len(jpgPath)-4] + ".png" // replace .jpg extension with .png out, err := os.Create(pngPath) if err != nil { return err } defer out.Close() // Decode the JPEG image and encode it as PNG img, err := jpeg.Decode(f) if err != nil { return err } err = png.Encode(out, img) if err != nil { return err } return nil } func GetImageCompressionType(path string) (string, error) { // 打开文件 file, err := os.Open(path) if err != nil { return "", err } defer file.Close() // 创建 bufio.Reader reader := bufio.NewReader(file) // 解码图像 _, format, err := image.DecodeConfig(reader) if err != nil { fmt.Println("err: ", err) return "", err } fmt.Println("format: ", format) // 返回压缩类型 return format, nil }