Java、Objective-C 傳送圖片到遊戲引擎
讓 Java、Objective-C 語言能夠將圖片轉為 Unity、Unreal 的教學,主要也是我自己研究了一段時間,相關的文件真的蠻少的。

前言
我的工作是串接 iOS、Android 的原生功能 e.g. , IAP、Permission、AlertDialog ,來讓公司的遊戲專案可以不用去考慮平台的原生功能,專心的處理遊戲及商業邏輯。
功能需求
這一次的功能需求起因是遊戲專案需要讓玩家可以選擇頭像,但原先使用的 Unity 套件沒有繼續更新支援新版 Android 日漸嚴格的隱私權政策,所以就把這個 case 轉來我們團隊了 !
作法簡介
我的作法是將圖片先轉為 Byte Array 再轉為 base64 字串傳到引擎內再去處理。
處理順序
- Convert to byte array
- Encode to base64
- Send message to engine
- Engine base64 decode
- Convert to engine texture
引擎坑
Unity 支援 base 64 帶有 \n
Unreal 不支援 base64 帶有 \n
Objective-C
// 選擇照片的 Callback
-(void)onSelectPhotoSuccess:(UIImage*)choseImage
{
// 壓縮值(%)
CGFloat quality = 0.8;
// Convert image to NSData
NSData* data = UIImageJPEGRepresentation(choseImage, quality);
[self sendPhotoDataToEngine: data];
}
// 傳送處理過的 data 給遊戲引擎
-(void)sendPhotoDataToEngine:(NSData*)photoData
{
if (photoData != nil)
{
// no \n
NSString* base64Str = [photoData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
// default
NSString* base64StrWithLine = [photoData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
// Use your way to Engine
}
}
Java
// 選擇照片的 Callback
private void onSelectPhotoSuccess(Bitmap bitmap)
{
float quality = 80;
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
sendPhotoDataToEngine(out.toByteArray());
}
// 傳送處理過的 data 給遊戲引擎
private void sendPhotoDataToEngine(byte[] data)
{
String resultString = "";
// Unity support Default
resultString = Base64.encodeToString(data, Base64.DEFAULT);
// Unreal doesn't support DEFAULT
resultString = Base64.encodeToString(data, Base64.NO_WARP);
// Use your way to Engine
}
Unity
/// <summary>
/// 處理傳來的 base64
/// </summary>
/// <param name="base64Str">圖片資訊</param>
private void ConvertBase64ToBytes(string base64Str)
{
byte[] bytes = System.Convert.FromBase64String(base64Str);
ConvertBytesToTexture(bytes);
}
/// <summary>
/// 轉換為 Texture
/// </summary>
/// <param name="photoByteArray">圖片byte array</param>
private void ConvertBytesToTexture(Byte[] photoByteArray)
{
if (photoByteArray != null)
{
// 如果有需要,也可以把長寬從 Java、iOS 傳過來
var photoTexture = new Texture2D(width, height);
photoTexture.LoadImage(photoByteArray);
}
}
Unreal
// 略過相關的 C、Jni 類型轉換
void Sample::ConvertBase64ToTexture2D(FString base64Str)
{
TArray<uint8> sourceData;
FBase64::Decode(base64Str, sourceData);
UTexture2D* outTexture = FImageUtils::ImportBufferAsTexture2D(sourceData);
}