Add bitmap trimming

This commit is contained in:
2019-03-22 11:22:24 +07:00
parent ca52ce93d2
commit 65bc86a390
10 changed files with 176 additions and 48 deletions

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 578397740ed1a4057b143176c5327496 guid: a296b112d7567477783e9c16409b3db5
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
userData: userData:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ec6ecc878c78246c7b2dda1979aae2c2
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,5 @@
###### Version 1.3.15 ###### Version 1.3.15
* Add bitmap trimming
* Fix preview leaks in the Editor mode * Fix preview leaks in the Editor mode
###### Version 1.3.14 ###### Version 1.3.14

View File

@@ -111,7 +111,7 @@ namespace FTEditor.Postprocessors {
static Texture2D LoadTextureFromData(SwfBitmapData bitmap) { static Texture2D LoadTextureFromData(SwfBitmapData bitmap) {
var texture = new Texture2D( var texture = new Texture2D(
bitmap.RealWidth, bitmap.RealHeight, bitmap.TrimmedRect.width, bitmap.TrimmedRect.height,
TextureFormat.ARGB32, false); TextureFormat.ARGB32, false);
texture.LoadRawTextureData(bitmap.ARGB32); texture.LoadRawTextureData(bitmap.ARGB32);
return texture; return texture;
@@ -357,14 +357,15 @@ namespace FTEditor.Postprocessors {
var bitmap = inst != null var bitmap = inst != null
? FindBitmapFromAssetData(data, inst.Bitmap) ? FindBitmapFromAssetData(data, inst.Bitmap)
: null; : null;
while ( bitmap != null && bitmap.Redirect > 0 ) {
bitmap = FindBitmapFromAssetData(data, bitmap.Redirect);
}
if ( bitmap != null ) { if ( bitmap != null ) {
var width = bitmap.RealWidth / 20.0f; var tr = bitmap.TrimmedRect;
var height = bitmap.RealHeight / 20.0f; var v0 = new Vector2(tr.xMin, tr.yMin) / 20.0f;
var v1 = new Vector2(tr.xMax, tr.yMin) / 20.0f;
var v0 = new Vector2( 0, 0); var v2 = new Vector2(tr.xMax, tr.yMax) / 20.0f;
var v1 = new Vector2(width, 0); var v3 = new Vector2(tr.xMin, tr.yMax) / 20.0f;
var v2 = new Vector2(width, height);
var v3 = new Vector2( 0, height);
var matrix = var matrix =
Matrix4x4.Scale( Matrix4x4.Scale(

View File

@@ -402,14 +402,58 @@ namespace FTEditor.Postprocessors {
return library.Defines return library.Defines
.Where (p => p.Value.Type == SwfLibraryDefineType.Bitmap) .Where (p => p.Value.Type == SwfLibraryDefineType.Bitmap)
.ToDictionary(p => p.Key, p => p.Value as SwfLibraryBitmapDefine) .ToDictionary(p => p.Key, p => p.Value as SwfLibraryBitmapDefine)
.Select (p => new SwfBitmapData{ .Select (p => ConvertBitmap(p.Key, p.Value))
Id = p.Key,
ARGB32 = p.Value.ARGB32,
Redirect = p.Value.Redirect,
RealWidth = p.Value.Width,
RealHeight = p.Value.Height})
.ToList(); .ToList();
} }
static SwfBitmapData ConvertBitmap(ushort id, SwfLibraryBitmapDefine bitmap) {
var trimmed_rect = bitmap.Redirect > 0
? new SwfRectIntData(bitmap.Width, bitmap.Height)
: FindBitmapTrimmedRect(bitmap);
var trimmed_argb32 = bitmap.Redirect > 0
? bitmap.ARGB32
: TrimBitmapByRect(bitmap, trimmed_rect);
return new SwfBitmapData{
Id = id,
ARGB32 = trimmed_argb32,
Redirect = bitmap.Redirect,
TrimmedRect = trimmed_rect};
}
static SwfRectIntData FindBitmapTrimmedRect(SwfLibraryBitmapDefine bitmap) {
var rect = new SwfRectIntData{
xMin = bitmap.Width,
yMin = bitmap.Height,
xMax = 0,
yMax = 0};
for ( var i = 0; i < bitmap.Height; ++i ) {
for ( var j = 0; j < bitmap.Width; ++j ) {
var a = bitmap.ARGB32[(j + i * bitmap.Width) * 4];
if ( a > 0 ) {
rect.xMin = Mathf.Min(j, rect.xMin);
rect.yMin = Mathf.Min(i, rect.yMin);
rect.xMax = Mathf.Max(j + 1, rect.xMax);
rect.yMax = Mathf.Max(i + 1, rect.yMax);
}
}
}
return rect.width < 1 || rect.height < 1
? new SwfRectIntData(0, 0, 1, 1)
: rect;
}
static byte[] TrimBitmapByRect(SwfLibraryBitmapDefine bitmap, SwfRectIntData rect) {
var trimmed_argb32 = new byte[rect.area * 4];
for ( var i = 0; i < rect.height; ++i ) {
var src_index = rect.xMin + (rect.yMin + i) * bitmap.Width;
var dst_index = i * rect.width;
Array.Copy(
bitmap.ARGB32, src_index * 4,
trimmed_argb32, dst_index * 4,
rect.width * 4);
}
return trimmed_argb32;
}
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------

View File

@@ -60,22 +60,96 @@ namespace FTEditor {
public float yMin; public float yMin;
public float yMax; public float yMax;
public SwfRectData(float w, float h) {
this.xMin = 0;
this.yMin = 0;
this.xMax = w;
this.yMax = h;
}
public SwfRectData(float x, float y, float w, float h) {
this.xMin = x;
this.yMin = y;
this.xMax = x + w;
this.yMax = y + h;
}
public float width {
get {
return xMax - xMin;
}
}
public float height {
get {
return yMax - yMin;
}
}
public float area {
get {
return width * height;
}
}
public static SwfRectData identity { public static SwfRectData identity {
get { get {
return new SwfRectData{ return new SwfRectData(0.0f, 0.0f, 0.0f, 0.0f);
xMin = 0.0f,
xMax = 0.0f,
yMin = 0.0f,
yMax = 0.0f};
} }
} }
public static SwfRectData FromURect(Rect rect) { public static SwfRectData FromURect(Rect rect) {
return new SwfRectData{ return new SwfRectData(rect.xMin, rect.yMin, rect.width, rect.height);
xMin = rect.xMin, }
xMax = rect.xMax, }
yMin = rect.yMin,
yMax = rect.yMax}; [System.Serializable]
struct SwfRectIntData {
public int xMin;
public int xMax;
public int yMin;
public int yMax;
public SwfRectIntData(int w, int h) {
this.xMin = 0;
this.yMin = 0;
this.xMax = w;
this.yMax = h;
}
public SwfRectIntData(int x, int y, int w, int h) {
this.xMin = x;
this.yMin = y;
this.xMax = x + w;
this.yMax = y + h;
}
public int width {
get {
return xMax - xMin;
}
}
public int height {
get {
return yMax - yMin;
}
}
public int area {
get {
return width * height;
}
}
public static SwfRectIntData identity {
get {
return new SwfRectIntData(0, 0, 0, 0);
}
}
public static SwfRectIntData FromURect(RectInt rect) {
return new SwfRectIntData(rect.xMin, rect.yMin, rect.width, rect.height);
} }
} }
@@ -187,41 +261,40 @@ namespace FTEditor {
Masked, Masked,
MaskReset MaskReset
} }
public Types Type = Types.Group; public Types Type = Types.Group;
public ushort ClipDepth = 0; public ushort ClipDepth = 0;
public ushort Bitmap = 0; public ushort Bitmap = 0;
public SwfMatrixData Matrix = SwfMatrixData.identity; public SwfMatrixData Matrix = SwfMatrixData.identity;
public SwfBlendModeData BlendMode = SwfBlendModeData.identity; public SwfBlendModeData BlendMode = SwfBlendModeData.identity;
public SwfColorTransData ColorTrans = SwfColorTransData.identity; public SwfColorTransData ColorTrans = SwfColorTransData.identity;
} }
[System.Serializable] [System.Serializable]
class SwfFrameData { class SwfFrameData {
public string Anchor = string.Empty; public string Anchor = string.Empty;
public List<string> Labels = new List<string>(); public List<string> Labels = new List<string>();
public List<SwfInstanceData> Instances = new List<SwfInstanceData>(); public List<SwfInstanceData> Instances = new List<SwfInstanceData>();
} }
[System.Serializable] [System.Serializable]
class SwfSymbolData { class SwfSymbolData {
public string Name = string.Empty; public string Name = string.Empty;
public List<SwfFrameData> Frames = new List<SwfFrameData>(); public List<SwfFrameData> Frames = new List<SwfFrameData>();
} }
[System.Serializable] [System.Serializable]
class SwfBitmapData { class SwfBitmapData {
public ushort Id = 0; public ushort Id = 0;
public byte[] ARGB32 = new byte[0]; public byte[] ARGB32 = new byte[0];
public ushort Redirect = 0; public ushort Redirect = 0;
public int RealWidth = 0; public SwfRectData SourceRect = SwfRectData.identity;
public int RealHeight = 0; public SwfRectIntData TrimmedRect = SwfRectIntData.identity;
public SwfRectData SourceRect = SwfRectData.identity;
} }
[System.Serializable] [System.Serializable]
class SwfAssetData { class SwfAssetData {
public float FrameRate = 0.0f; public float FrameRate = 0.0f;
public List<SwfSymbolData> Symbols = new List<SwfSymbolData>(); public List<SwfSymbolData> Symbols = new List<SwfSymbolData>();
public List<SwfBitmapData> Bitmaps = new List<SwfBitmapData>(); public List<SwfBitmapData> Bitmaps = new List<SwfBitmapData>();
} }
} }

View File

@@ -15,7 +15,7 @@ namespace FTRuntime {
AutomaticTruecolor = 2 AutomaticTruecolor = 2
} }
[SwfPowerOfTwoIfAttribute(5, 13, "AtlasPowerOfTwo")] [SwfPowerOfTwoIf(5, 13, "AtlasPowerOfTwo")]
public int MaxAtlasSize; public int MaxAtlasSize;
[SwfIntRange(0, int.MaxValue)] [SwfIntRange(0, int.MaxValue)]
public int AtlasPadding; public int AtlasPadding;

View File

@@ -2,7 +2,7 @@
public static class SwfVersion { public static class SwfVersion {
public const int Major = 1; public const int Major = 1;
public const int Minor = 3; public const int Minor = 3;
public const int Revision = 11; public const int Revision = 15;
public static string AsString { public static string AsString {
get { get {

View File

@@ -75,7 +75,9 @@ UNITY_HALF_TEXEL_OFFSET
**** DONE Утечка превью в редакторе **** DONE Утечка превью в редакторе
*** Улучшения *** Улучшения
**** TODO Выводить в лог успешную конвертацию с контекстом **** TODO Выводить в лог успешную конвертацию с контекстом
**** TODO Триммить изображения из swf (adou.fla) **** TODO Добавить версию в SwfAsset
**** TODO Опциональный тримминг
**** DONE Триммить изображения из swf (adou.fla)
** DONE Версия 1.3.14 ** DONE Версия 1.3.14
*** Баги *** Баги
**** DONE Сломалась компиляция в 2018.3.2f1 **** DONE Сломалась компиляция в 2018.3.2f1