openai_image.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package dto
  2. import (
  3. "encoding/json"
  4. "one-api/common"
  5. "one-api/types"
  6. "reflect"
  7. "strings"
  8. "github.com/gin-gonic/gin"
  9. )
  10. type ImageRequest struct {
  11. Model string `json:"model"`
  12. Prompt string `json:"prompt" binding:"required"`
  13. N uint `json:"n,omitempty"`
  14. Size string `json:"size,omitempty"`
  15. Quality string `json:"quality,omitempty"`
  16. ResponseFormat string `json:"response_format,omitempty"`
  17. Style json.RawMessage `json:"style,omitempty"`
  18. User json.RawMessage `json:"user,omitempty"`
  19. ExtraFields json.RawMessage `json:"extra_fields,omitempty"`
  20. Background json.RawMessage `json:"background,omitempty"`
  21. Moderation json.RawMessage `json:"moderation,omitempty"`
  22. OutputFormat json.RawMessage `json:"output_format,omitempty"`
  23. OutputCompression json.RawMessage `json:"output_compression,omitempty"`
  24. PartialImages json.RawMessage `json:"partial_images,omitempty"`
  25. // Stream bool `json:"stream,omitempty"`
  26. Watermark *bool `json:"watermark,omitempty"`
  27. // 用匿名参数接收额外参数
  28. Extra map[string]json.RawMessage `json:"-"`
  29. }
  30. func (i *ImageRequest) UnmarshalJSON(data []byte) error {
  31. // 先解析成 map[string]interface{}
  32. var rawMap map[string]json.RawMessage
  33. if err := common.Unmarshal(data, &rawMap); err != nil {
  34. return err
  35. }
  36. // 用 struct tag 获取所有已定义字段名
  37. knownFields := GetJSONFieldNames(reflect.TypeOf(*i))
  38. // 再正常解析已定义字段
  39. type Alias ImageRequest
  40. var known Alias
  41. if err := common.Unmarshal(data, &known); err != nil {
  42. return err
  43. }
  44. *i = ImageRequest(known)
  45. // 提取多余字段
  46. i.Extra = make(map[string]json.RawMessage)
  47. for k, v := range rawMap {
  48. if _, ok := knownFields[k]; !ok {
  49. i.Extra[k] = v
  50. }
  51. }
  52. return nil
  53. }
  54. func GetJSONFieldNames(t reflect.Type) map[string]struct{} {
  55. fields := make(map[string]struct{})
  56. for i := 0; i < t.NumField(); i++ {
  57. field := t.Field(i)
  58. // 跳过匿名字段(例如 ExtraFields)
  59. if field.Anonymous {
  60. continue
  61. }
  62. tag := field.Tag.Get("json")
  63. if tag == "-" || tag == "" {
  64. continue
  65. }
  66. // 取逗号前字段名(排除 omitempty 等)
  67. name := tag
  68. if commaIdx := indexComma(tag); commaIdx != -1 {
  69. name = tag[:commaIdx]
  70. }
  71. fields[name] = struct{}{}
  72. }
  73. return fields
  74. }
  75. func indexComma(s string) int {
  76. for i := 0; i < len(s); i++ {
  77. if s[i] == ',' {
  78. return i
  79. }
  80. }
  81. return -1
  82. }
  83. func (i *ImageRequest) GetTokenCountMeta() *types.TokenCountMeta {
  84. var sizeRatio = 1.0
  85. var qualityRatio = 1.0
  86. if strings.HasPrefix(i.Model, "dall-e") {
  87. // Size
  88. if i.Size == "256x256" {
  89. sizeRatio = 0.4
  90. } else if i.Size == "512x512" {
  91. sizeRatio = 0.45
  92. } else if i.Size == "1024x1024" {
  93. sizeRatio = 1
  94. } else if i.Size == "1024x1792" || i.Size == "1792x1024" {
  95. sizeRatio = 2
  96. }
  97. if i.Model == "dall-e-3" && i.Quality == "hd" {
  98. qualityRatio = 2.0
  99. if i.Size == "1024x1792" || i.Size == "1792x1024" {
  100. qualityRatio = 1.5
  101. }
  102. }
  103. }
  104. // not support token count for dalle
  105. return &types.TokenCountMeta{
  106. CombineText: i.Prompt,
  107. MaxTokens: 1584,
  108. ImagePriceRatio: sizeRatio * qualityRatio * float64(i.N),
  109. }
  110. }
  111. func (i *ImageRequest) IsStream(c *gin.Context) bool {
  112. return false
  113. }
  114. func (i *ImageRequest) SetModelName(modelName string) {
  115. if modelName != "" {
  116. i.Model = modelName
  117. }
  118. }
  119. type ImageResponse struct {
  120. Data []ImageData `json:"data"`
  121. Created int64 `json:"created"`
  122. Extra any `json:"extra,omitempty"`
  123. }
  124. type ImageData struct {
  125. Url string `json:"url"`
  126. B64Json string `json:"b64_json"`
  127. RevisedPrompt string `json:"revised_prompt"`
  128. }