This is my code.
I also have code that converts rectangles into squares.
I uploaded a 30.8MB (6378x19370, jpeg) image for testing (for an extreme test…).
After loading large images a few times, a memory error eventually occurs.
//Call Function
public void ChangeImage(MeshRenderer meshRender , string imgUrl, string propertiesName="_BaseMap")
{
if (imgCo!=null )
{
StopCoroutine(imgCo);
}
if (imgUrl.Length <= 0)
{
meshRender.material.SetInt("_useImage", 1);
meshRender.material.SetTexture(propertiesName, clearTexture);
}
else
{
imgCo = StartCoroutine(DownloadImg(imgUrl, (texture) =>
{
Texture resizeTexture = RectToSqure(texture);
meshRender.material.SetInt("_useImage", 1);
meshRender.material.SetTexture(propertiesName, resizeTexture);
}));
}
}
//Download Image
public IEnumerator DownloadImg(string url, Action<Texture2D> GetTexture)
{
using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(url))
{
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success)
{
Texture2D texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
GetTexture(texture);
imgCo = null;
}
else
{
Debug.Log("DownloadError :" + url);
}
www.Dispose();
}
yield return null;
}
public Texture2D RectToSqure(Texture2D inputTexture, bool isflip=false)
{
if (inputTexture == null)
{
Debug.Log("InputTexture null ");
return null;
}
Mat originalMat = new Mat(inputTexture.height, inputTexture.width, CvType.CV_8UC4);
OpenCVForUnity.UnityUtils.Utils.texture2DToMat(inputTexture, originalMat);
DestroyImmediate(inputTexture);
inputTexture = null;
originalMat = ResizeIfNeeded(originalMat, 2048, 2048);
int maxLength = Mathf.Max(originalMat.width(), originalMat.height());
Mat squareMat = new Mat(maxLength, maxLength, originalMat.type(), new Scalar(0, 0, 0));
//
int dx = (maxLength - originalMat.width()) / 2;
int dy = (maxLength - originalMat.height()) / 2;
//Mat submat = squareMat.submat(dy, dy + originalMat.height(), dx, dx + originalMat.width());
originalMat.copyTo(squareMat.submat(dy, dy + originalMat.height(), dx, dx + originalMat.width()));
if (isflip==true)
{
Core.flip(squareMat, squareMat, 0);
}
Texture2D outputTexture = new Texture2D(squareMat.cols(), squareMat.rows(), TextureFormat.RGBA32, false);
OpenCVForUnity.UnityUtils.Utils.matToTexture2D(squareMat, outputTexture);
originalMat.release();
squareMat.release();
originalMat = null;
squareMat = null;
return outputTexture;
}
Mat ResizeIfNeeded(Mat image, int maxWidth, int maxHeight)
{
// Current Size
Size size = image.size();
//When image size big
if (size.width > maxWidth || size.height > maxHeight)
{
float aspectRatio = (float)size.width / (float)size.height;
int newWidth, newHeight;
if (aspectRatio > 1)
{
newWidth = maxWidth;
newHeight = (int)(maxWidth / aspectRatio);
}
else
{
newHeight = maxHeight;
newWidth = (int)(maxHeight * aspectRatio);
}
Imgproc.resize(image, image, new Size(newWidth, newHeight));
}
return image;
}