[英]Convert Texture2D to Byte[] using EncodeToJPG (in OpenVR)
[英]unity texture2d EncodeToJPG transparent black
我有一個紋理用戶繪制(在移動設備上),我想將其編碼為jpg,以便用戶可以共享,但我發現轉換部分將在編碼的jpg中為黑色:
但我沒有找到任何重寫的texture2d.EncodeToJPG()
方法來做到這一點。
有任何想法嗎?
鳥的翅膀是專門為Color.white
繪制的,所以在編碼的jpg中它可能是白色的。
我終於通過以下方式完成了這項工作:
Color32[] pixels = text.GetPixels32();
Color blackTransparent = Color.black;
blackTransparent.a = 0;
for(int i = 0;i < pixels.Length; i++)
{
if(pixels[i] == blackTransparent)
{
pixels[i] = Color.white;
}
}
text.SetPixels32(pixels);
text.Apply();
但這將遍歷紋理的所有像素,如果有人有更好的方法,請告訴我們。
我們發現使用上面的代碼在jpg上會有一些邊緣(當遇到黑線時),可能需要一些圖形處理知識才能解決這個問題?
Texture2D text = new Texture2D(1, 1, TextureFormat.PVRTC_RGBA4, false);
byte[] imagebytes = null;
string path = "image/path/sample.png";
if (System.IO.File.Exists(path))
{
Debug.Log(" really load file from " + path);
imagebytes = System.IO.File.ReadAllBytes(path);
}
text.LoadImage(imagebytes, false);
對於您的第一個問題編輯,詢問如何改進循環遍歷所有像素的代碼,您可以。 只需用for (int i = 0; i < pixels.Length; i += 4)
替換for(int i = 0;i < pixels.Length; i++)
for (int i = 0; i < pixels.Length; i += 4)
然后訪問i+0
到i+3
內的每個索引環。 循環速度快約4倍 。
Color32[] pixels = text.GetPixels32();
Color blackTransparent = Color.black;
Color overwriteColor = Color.white;
blackTransparent.a = 0;
for (int i = 0; i < pixels.Length; i += 4)
{
if (pixels[i] == blackTransparent)
pixels[i] = overwriteColor;
if (pixels[i + 1] == blackTransparent)
pixels[i + 1] = overwriteColor;
if (pixels[i + 2] == blackTransparent)
pixels[i + 2] = overwriteColor;
if (pixels[i + 3] == blackTransparent)
pixels[i + 3] = overwriteColor;
}
text.SetPixels32(pixels);
text.Apply(true);
雖然,這兩個代碼都會遇到與第二次編輯中提到的相同的鋸齒狀線問題。
要修復它,請不要將像素直接與==
符號進行比較。 使用一個讓您使用閾值來比較顏色而不僅僅是數字的函數。 這是我用來比較Unity中RGB顏色的功能,我建議你開始使用它。
然后,您必須手動檢查alpha是低於還是等於某個值。 90
的值似乎對此有用。
這是腳本的樣子:
Color32[] pixels = text.GetPixels32();
Color blackTransparent = Color.black;
for (int i = 0; i < pixels.Length; i += 4)
{
checkPixel(ref pixels[i], blackTransparent, Color.white, 600);
checkPixel(ref pixels[i + 1], blackTransparent, Color.white, 600);
checkPixel(ref pixels[i + 2], blackTransparent, Color.white, 600);
checkPixel(ref pixels[i + 3], blackTransparent, Color.white, 600);
}
text.SetPixels32(pixels);
text.Apply();
函數checkPixel
和ColourDistance
函數:
void checkPixel(ref Color32 pixel1, Color32 pixel2, Color32 newColor, int threshold)
{
if (ColourDistance(pixel1, pixel2) <= threshold)
{
if (pixel1.a <= 90)
{
pixel1 = Color.white;
}
}
}
private static double ColourDistance(Color32 c1, Color32 c2)
{
double rmean = (c1.r + c2.r) / 2;
int r = c1.r - c2.r;
int g = c1.g - c2.g;
int b = c1.b - c2.b;
double weightR = 2 + rmean / 256;
double weightG = 4.0;
double weightB = 2 + (255 - rmean) / 256;
return Math.Sqrt(weightR * r * r + weightG * g * g + weightB * b * b);
}
這就是結果:
它仍然可以改進。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.