一天中的好时光,我想从用户本地计算机加载任何大小的图像到Unity Web应用程序。我搜索this article但我经常得到#stack; flowoverflow"我尝试加载大尺寸图片时出现异常。
我得到" stackoverflow"在这次电话会议之后。
sendResult(dataUrl);
这是统一网络插件代码:
var UnityBridge = {
LoadImage: function()
{
// Because unity is currently bad at JavaScript we can't use standard
// JavaScript idioms like closures so we have to use global variables :(
window.becauseUnitysBadWithJavacript_getImageFromBrowser =
window.becauseUnitysBadWithJavacript_getImageFromBrowser || {
busy: false,
initialized: false,
rootDisplayStyle: null, // style to make root element visible
root_: null, // root element of form
ctx_: null // canvas for getting image data;
};
var g = window.becauseUnitysBadWithJavacript_getImageFromBrowser;
if (g.busy) {
// Don't let multiple requests come in
return;
}
g.busy = true;
if (!g.initialized) {
g.initialized = true;
g.ctx = window.document.createElement("canvas").getContext("2d");
// Append a form to the page (more self contained than editing the HTML?)
g.root = window.document.createElement("div");
g.root.innerHTML = [
'<style> ',
'.getimage { ',
' position: absolute; ',
' left: 0; ',
' top: 0; ',
' width: 100%; ',
' height: 100%; ',
' display: -webkit-flex; ',
' display: flex; ',
' -webkit-flex-flow: column; ',
' flex-flow: column; ',
' -webkit-justify-content: center; ',
' -webkit-align-content: center; ',
' -webkit-align-items: center; ',
' ',
' justify-content: center; ',
' align-content: center; ',
' align-items: center; ',
' ',
' z-index: 2; ',
' color: white; ',
' background-color: rgba(0,0,0,0.8); ',
' font: sans-serif; ',
' font-size: x-large; ',
'} ',
'.getimage a, ',
'.getimage label { ',
' font-size: x-large; ',
' background-color: #666; ',
' border-radius: 0.5em; ',
' border: 1px solid black; ',
' padding: 0.5em; ',
' margin: 0.25em; ',
' outline: none; ',
' display: inline-block; ',
'} ',
'.getimage input { ',
' display: none; ',
'} ',
'</style> ',
'<div class="getimage"> ',
' <div> ',
' <label for="photo">Кликните чтобы выбрать изображенние</label> ',
' <input id="photo" type="file" accept="image/*"/><br/>',
' <a>Отмена</a> ',
' </div> ',
'</div> ',
].join('\n');
var input = g.root.querySelector("input");
input.addEventListener('change', getPic);
// prevent clicking in input or label from canceling
input.addEventListener('click', preventOtherClicks);
var label = g.root.querySelector("label");
label.addEventListener('click', preventOtherClicks);
// clicking cancel or outside cancels
var cancel = g.root.querySelector("a"); // there's only one
cancel.addEventListener('click', handleCancel);
var getImage = g.root.querySelector(".getimage");
getImage.addEventListener('click', handleCancel);
// remember the original style
g.rootDisplayStyle = g.root.style.display;
window.document.body.appendChild(g.root);
}
// make it visible
g.root.style.display = g.rootDisplayStyle;
function preventOtherClicks(evt) {
evt.stopPropagation();
}
function getPic(evt) {
evt.stopPropagation();
var fileInput = evt.target.files;
if (!fileInput || !fileInput.length) {
return sendError("no image selected");
}
var picURL = window.URL.createObjectURL(fileInput[0]);
var img = new window.Image();
img.addEventListener('load', handleImageLoad);
img.addEventListener('error', handleImageError);
img.src = picURL;
}
function handleCancel(evt) {
evt.stopPropagation();
evt.preventDefault();
sendError("cancelled");
}
function handleImageError(evt) {
sendError("Could not get image");
}
function handleImageLoad(evt) {
var img = evt.target;
console.log(img);
window.URL.revokeObjectURL(img.src);
// We probably don't want the fullsize image. It might be 3000x2000 pixels or something too big
const screenWidth = 1280;
const screenHeight = 800;
g.ctx.canvas.width = img.width;
g.ctx.canvas.height = img.height;
console.log("Image width: " + img.width + " height: " + img.height);
coefficientWidth = screenWidth / img.width;
coefficientHeight = screenHeight / img.height;
if (g.ctx.canvas.width > screenWidth || g.ctx.canvas.height > screenHeight) {
// scale image if it bigger UnityPlayer
if (coefficientWidth < coefficientHeight) {
g.ctx.canvas.width *= coefficientWidth;
g.ctx.canvas.height *= coefficientWidth;
console.log("if width > height then canvas width : " + g.ctx.canvas.width + " height: " + g.ctx.canvas.height);
} else {
g.ctx.canvas.width *= coefficientHeight;
g.ctx.canvas.height *= coefficientHeight;
console.log("if width < height then canvas width : " + g.ctx.canvas.width + " height: " + g.ctx.canvas.height);
}
}
g.ctx.drawImage(img, 0, 0, g.ctx.canvas.width, g.ctx.canvas.height);
console.log("This is dataUrl: " + g.ctx.canvas.toDataURL());
var dataUrl = g.ctx.canvas.toDataURL();
// free the canvas memory (could probably be zero)
g.ctx.canvas.width = 1;
g.ctx.canvas.height = 1;
sendResult(dataUrl);
g.busy = false;
}
function sendError(msg) {
sendResult("error: " + msg);
}
function hide() {
g.root.style.display = "none";
}
function sendResult(result) {
hide();
g.busy = false;
SendMessage("NativeBridge", "OnPick", result);
}
}
};
mergeInto(LibraryManager.library, UnityBridge);
请帮帮我。
答案 0 :(得分:0)
您必须将从 js 发送回的字符串分成块,因为 Unity 无法处理非常大的字符串。做这样的事情:
function sendResult(result,offset) {
hide();
g.busy = false;
//Split string into smaller chunks as Unity is too retarded to do it properly with large strings
var bufferSize=100000;
for (var x = offset; x < result.length; x+=bufferSize)
{
SendMessage(objectName, funcName, result.substring(x,Math.min(x+bufferSize,result.length)));
}
//Send EOF
SendMessage(objectName, funcName, 'EOF:');
}
然后在Unity中的接收代码中,是这样的:
private StringBuilder buffer = null;
public void receiveFile(string input)
{
if (input.StartsWith("ERROR:"))
{
buffer = null;
Debug.LogError(input);
return;
}
if (input.StartsWith("EOF:"))
{
string bufferText = buffer.ToString();
buffer = null;
byte[] data = System.Convert.FromBase64String(bufferText);
//Do something with data...
return;
}
else
{
if (buffer == null) buffer = new StringBuilder();
buffer.Append(input);
}
}