如何通过UnityWebRequest以Json格式向Django发送图片数据?
我来帮你补全并修正Unity与Django之间的图片交互方案——毕竟直接读图片文本转JSON肯定会出问题,咱们一步步来解决:
Unity 端代码实现
首先纠正你原来代码里的一个关键错误:图片是二进制文件,不能用File.ReadAllText读取,得转成Base64字符串再塞进JSON里,不然传过去的都是乱码。下面是完整的可运行代码:
using UnityEngine; using UnityEngine.Networking; using System.Collections; using System.IO; public class ImageUploader : MonoBehaviour { // 替换成你的Django接口地址(本地测试就是http://localhost:8000/upload-image/) [SerializeField] private string djangoApiUrl = "http://localhost:8000/upload-image/"; // 替换成你的图片路径,比如移动端可以用Application.persistentDataPath + "/test.png" [SerializeField] private string imagePath; public void onClickSendButton() { // 直接启动协程就行,不用单独存变量(除非你需要中途停止) StartCoroutine(UploadImageToDjango()); } IEnumerator UploadImageToDjango() { // 先检查图片是否存在 if (!File.Exists(imagePath)) { Debug.LogError($"找不到图片:{imagePath}"); yield break; } // 读取图片二进制数据并转成Base64(这是JSON传输二进制的标准操作) byte[] imageBytes = File.ReadAllBytes(imagePath); string imageBase64 = System.Convert.ToBase64String(imageBytes); // 构造JSON payload,把Base64字符串包进去 string jsonData = $"{{\"image_base64\": \"{imageBase64}\"}}"; byte[] requestBody = System.Text.Encoding.UTF8.GetBytes(jsonData); // 配置UnityWebRequest,用Raw上传JSON格式数据 using (UnityWebRequest uploadRequest = UnityWebRequest.PostWwwForm(djangoApiUrl, "")) { uploadRequest.uploadHandler = new UploadHandlerRaw(requestBody); uploadRequest.downloadHandler = new DownloadHandlerBuffer(); // 必须设置请求头为application/json,不然Django识别不了JSON格式 uploadRequest.SetRequestHeader("Content-Type", "application/json"); // 发送请求并等待响应 yield return uploadRequest.SendWebRequest(); // 处理结果 if (uploadRequest.result != UnityWebRequest.Result.Success) { Debug.LogError($"上传失败:{uploadRequest.error}"); } else { Debug.Log($"上传成功!Django返回:{uploadRequest.downloadHandler.text}"); } } } }
Django 端接收处理代码
接下来是Django这边的接口,负责接收Unity发过来的JSON,解码Base64并保存图片:
1. 配置路由(urls.py)
先在你的app的urls.py里加一条路由:
from django.urls import path from . import views urlpatterns = [ # 其他路由... path('upload-image/', views.upload_image, name='upload-image'), ]
2. 编写视图函数(views.py)
from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt import base64 import os from datetime import datetime # 本地测试可以暂时加@csrf_exempt跳过CSRF验证,正式环境一定要处理CSRF! @csrf_exempt def upload_image(request): if request.method != 'POST': return JsonResponse({'status': 'error', 'msg': '只接受POST请求'}, status=405) try: # 解析Unity发送的JSON数据 request_data = request.json image_base64 = request_data.get('image_base64') if not image_base64: return JsonResponse({'status': 'error', 'msg': '未收到图片数据'}, status=400) # 解码Base64为二进制图片 image_bytes = base64.b64decode(image_base64) # 生成唯一文件名,避免覆盖 timestamp = datetime.now().strftime("%Y%m%d%H%M%S") filename = f"unity_upload_{timestamp}.png" # 后缀根据你的图片格式改(比如jpg) # 保存路径,建议放在media目录下,记得提前创建uploaded_images文件夹 save_dir = os.path.join('media', 'uploaded_images') os.makedirs(save_dir, exist_ok=True) save_path = os.path.join(save_dir, filename) # 写入文件 with open(save_path, 'wb') as img_file: img_file.write(image_bytes) return JsonResponse({ 'status': 'success', 'msg': '图片上传成功', 'saved_path': save_path }) except Exception as e: return JsonResponse({'status': 'error', 'msg': str(e)}, status=500)
几个要注意的坑
- Unity端路径问题:移动端不要用绝对路径,用
Application.persistentDataPath来获取可读写的目录;PC端测试也要确保路径正确。 - Django的CSRF验证:正式环境别用
@csrf_exempt,可以让Unity先发送一个GET请求获取CSRF token,然后POST的时候把token放在请求头里。 - 跨域问题:如果Unity和Django不在同一域名下,要给Django装
django-cors-headers库配置跨域允许。 - 图片格式:如果你的图片是JPG,记得把代码里的后缀改成
.jpg,解码的时候不会有问题。
内容的提问来源于stack exchange,提问作者Boosil-guy
相关产品推荐
相关产品推荐

