返回提交历史
Modified
g4f/Provider/bing/upload_image.py
+21
-15
Modified
g4f/gui/client/html/index.html
+2
-2
Modified
g4f/gui/client/js/chat.v1.js
+7
-1
Modified
g4f/gui/server/backend.py
+1
-1
Modified
g4f/image.py
+14
-2
Modified
g4f/models.py
+6
-5
XFEstudio/gpt4free
Add upload svg image support Fix upload image in Bing Provider
07c944ad
代码差异
6 个文件
+51
-26
@@ -82,13 +82,16 @@ def build_image_upload_payload(image_bin: str, tone: str) -> Tuple[str, str]:
82
82
Tuple[str, str]: The data and boundary for the payload.
83
83
"""
84
84
boundary = "----WebKitFormBoundary" + ''.join(random.choices(string.ascii_letters + string.digits, k=16))
85
data = f"--{boundary}\r\n" \
86
f"Content-Disposition: form-data; name=\"knowledgeRequest\"\r\n\r\n" \
87
f"{json.dumps(build_knowledge_request(tone), ensure_ascii=False)}\r\n" \
88
f"--{boundary}\r\n" \
89
f"Content-Disposition: form-data; name=\"imageBase64\"\r\n\r\n" \
90
f"{image_bin}\r\n" \
91
f"--{boundary}--\r\n"
85
data = f"""--{boundary}
86
Content-Disposition: form-data; name="knowledgeRequest"
87
88
{json.dumps(build_knowledge_request(tone), ensure_ascii=False)}
89
--{boundary}
90
Content-Disposition: form-data; name="imageBase64"
91
92
{image_bin}
93
--{boundary}--
94
"""
92
95
return data, boundary
93
96
94
97
def build_knowledge_request(tone: str) -> dict:
@@ -102,14 +105,17 @@ def build_knowledge_request(tone: str) -> dict:
102
105
dict: The knowledge request payload.
103
106
"""
104
107
return {
105
'invokedSkills': ["ImageById"],
106
'subscriptionId': "Bing.Chat.Multimodal",
107
'invokedSkillsRequestData': {
108
'enableFaceBlur': True
109
},
110
'convoData': {
111
'convoid': "",
112
'convotone': tone
108
"imageInfo": {},
109
"knowledgeRequest": {
110
'invokedSkills': ["ImageById"],
111
'subscriptionId': "Bing.Chat.Multimodal",
112
'invokedSkillsRequestData': {
113
'enableFaceBlur': True
114
},
115
'convoData': {
116
'convoid': "",
117
'convotone': tone
118
}
113
119
}
114
120
}
115
121
@@ -115,11 +115,11 @@
115
115
<textarea id="message-input" placeholder="Ask a question" cols="30" rows="10"
116
116
style="white-space: pre-wrap;resize: none;"></textarea>
117
117
<label for="image" title="Works only with Bing and OpenaiChat">
118
<input type="file" id="image" name="image" accept="image/png, image/gif, image/jpeg" required/>
118
<input type="file" id="image" name="image" accept="image/png, image/gif, image/jpeg, image/svg+xml" required/>
119
119
<i class="fa-regular fa-image"></i>
120
120
</label>
121
121
<label for="file">
122
<input type="file" id="file" name="file" accept="text/plain, text/html, text/xml, application/json, text/javascript, .sh, .py, .php, .css, .yaml, .sql, .svg, .log, .csv, .twig, .md" required/>
122
<input type="file" id="file" name="file" accept="text/plain, text/html, text/xml, application/json, text/javascript, .sh, .py, .php, .css, .yaml, .sql, .log, .csv, .twig, .md" required/>
123
123
<i class="fa-solid fa-paperclip"></i>
124
124
</label>
125
125
<div id="send-button">
@@ -660,7 +660,13 @@ observer.observe(message_input, { attributes: true });
660
660
}
661
661
document.getElementById("version_text").innerHTML = text
662
662
})()
663
663
imageInput.addEventListener('click', async (event) => {
664
imageInput.value = '';
665
});
666
fileInput.addEventListener('click', async (event) => {
667
fileInput.value = '';
668
delete fileInput.dataset.text;
669
});
664
670
fileInput.addEventListener('change', async (event) => {
665
671
if (fileInput.files.length) {
666
672
type = fileInput.files[0].type;
@@ -137,7 +137,7 @@ class Backend_Api:
137
137
if 'image' in request.files:
138
138
file = request.files['image']
139
139
if file.filename != '' and is_allowed_extension(file.filename):
140
kwargs['image'] = to_image(file.stream)
140
kwargs['image'] = to_image(file.stream, file.filename.endswith('.svg'))
141
141
if 'json' in request.form:
142
142
json_data = json.loads(request.form['json'])
143
143
else:
@@ -4,9 +4,9 @@ import base64
4
4
from .typing import ImageType, Union
5
5
from PIL import Image
6
6
7
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp'}
7
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'}
8
8
9
def to_image(image: ImageType) -> Image.Image:
9
def to_image(image: ImageType, is_svg: bool = False) -> Image.Image:
10
10
"""
11
11
Converts the input image to a PIL Image object.
12
12
@@ -16,6 +16,16 @@ def to_image(image: ImageType) -> Image.Image:
16
16
Returns:
17
17
Image.Image: The converted PIL Image object.
18
18
"""
19
if is_svg:
20
try:
21
import cairosvg
22
except ImportError:
23
raise RuntimeError('Install "cairosvg" package for open svg images')
24
if not isinstance(image, bytes):
25
image = image.read()
26
buffer = BytesIO()
27
cairosvg.svg2png(image, write_to=buffer)
28
image = Image.open(buffer)
19
29
if isinstance(image, str):
20
30
is_data_uri_an_image(image)
21
31
image = extract_data_uri(image)
@@ -153,6 +163,8 @@ def to_base64(image: Image.Image, compression_rate: float) -> str:
153
163
str: The base64-encoded image.
154
164
"""
155
165
output_buffer = BytesIO()
166
if image.mode != "RGB":
167
image = image.convert('RGB')
156
168
image.save(output_buffer, format="JPEG", quality=int(compression_rate * 100))
157
169
return base64.b64encode(output_buffer.getvalue()).decode()
158
170
@@ -5,6 +5,7 @@ from .Provider import (
5
5
Chatgpt4Online,
6
6
ChatgptDemoAi,
7
7
GeminiProChat,
8
PerplexityAi,
8
9
ChatgptNext,
9
10
HuggingChat,
10
11
ChatgptDemo,
@@ -78,7 +79,7 @@ gpt_35_long = Model(
78
79
gpt_35_turbo = Model(
79
80
name = 'gpt-3.5-turbo',
80
81
base_provider = 'openai',
81
best_provider=RetryProvider([
82
best_provider = RetryProvider([
82
83
GptGo, You,
83
84
GptForLove, ChatBase,
84
85
Chatgpt4Online,
@@ -114,20 +115,20 @@ llama2_13b = Model(
114
115
llama2_70b = Model(
115
116
name = "meta-llama/Llama-2-70b-chat-hf",
116
117
base_provider = "huggingface",
117
best_provider = RetryProvider([Llama2, DeepInfra, HuggingChat])
118
best_provider = RetryProvider([Llama2, DeepInfra, HuggingChat, PerplexityAi])
118
119
)
119
120
120
121
# Mistal
121
122
mixtral_8x7b = Model(
122
123
name = "mistralai/Mixtral-8x7B-Instruct-v0.1",
123
124
base_provider = "huggingface",
124
best_provider = RetryProvider([DeepInfra, HuggingChat])
125
best_provider = RetryProvider([DeepInfra, HuggingChat, PerplexityAi])
125
126
)
126
127
127
128
mistral_7b = Model(
128
129
name = "mistralai/Mistral-7B-Instruct-v0.1",
129
130
base_provider = "huggingface",
130
best_provider = RetryProvider([DeepInfra, HuggingChat])
131
best_provider = RetryProvider([DeepInfra, HuggingChat, PerplexityAi])
131
132
)
132
133
133
134
# Dolphin
@@ -311,7 +312,7 @@ llama70b_v2_chat = Model(
311
312
pi = Model(
312
313
name = 'pi',
313
314
base_provider = 'inflection',
314
best_provider=Pi
315
best_provider = Pi
315
316
)
316
317
317
318
class ModelUtils: