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
guid: 578397740ed1a4057b143176c5327496
guid: a296b112d7567477783e9c16409b3db5
DefaultImporter:
externalObjects: {}
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
* Add bitmap trimming
* Fix preview leaks in the Editor mode
###### Version 1.3.14

View File

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

View File

@@ -402,14 +402,58 @@ namespace FTEditor.Postprocessors {
return library.Defines
.Where (p => p.Value.Type == SwfLibraryDefineType.Bitmap)
.ToDictionary(p => p.Key, p => p.Value as SwfLibraryBitmapDefine)
.Select (p => new SwfBitmapData{
Id = p.Key,
ARGB32 = p.Value.ARGB32,
Redirect = p.Value.Redirect,
RealWidth = p.Value.Width,
RealHeight = p.Value.Height})
.Select (p => ConvertBitmap(p.Key, p.Value))
.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 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 {
get {
return new SwfRectData{
xMin = 0.0f,
xMax = 0.0f,
yMin = 0.0f,
yMax = 0.0f};
return new SwfRectData(0.0f, 0.0f, 0.0f, 0.0f);
}
}
public static SwfRectData FromURect(Rect rect) {
return new SwfRectData{
xMin = rect.xMin,
xMax = rect.xMax,
yMin = rect.yMin,
yMax = rect.yMax};
return new SwfRectData(rect.xMin, rect.yMin, rect.width, rect.height);
}
}
[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,
MaskReset
}
public Types Type = Types.Group;
public ushort ClipDepth = 0;
public ushort Bitmap = 0;
public SwfMatrixData Matrix = SwfMatrixData.identity;
public SwfBlendModeData BlendMode = SwfBlendModeData.identity;
public SwfColorTransData ColorTrans = SwfColorTransData.identity;
public Types Type = Types.Group;
public ushort ClipDepth = 0;
public ushort Bitmap = 0;
public SwfMatrixData Matrix = SwfMatrixData.identity;
public SwfBlendModeData BlendMode = SwfBlendModeData.identity;
public SwfColorTransData ColorTrans = SwfColorTransData.identity;
}
[System.Serializable]
class SwfFrameData {
public string Anchor = string.Empty;
public List<string> Labels = new List<string>();
public List<SwfInstanceData> Instances = new List<SwfInstanceData>();
public string Anchor = string.Empty;
public List<string> Labels = new List<string>();
public List<SwfInstanceData> Instances = new List<SwfInstanceData>();
}
[System.Serializable]
class SwfSymbolData {
public string Name = string.Empty;
public List<SwfFrameData> Frames = new List<SwfFrameData>();
public string Name = string.Empty;
public List<SwfFrameData> Frames = new List<SwfFrameData>();
}
[System.Serializable]
class SwfBitmapData {
public ushort Id = 0;
public byte[] ARGB32 = new byte[0];
public ushort Redirect = 0;
public int RealWidth = 0;
public int RealHeight = 0;
public SwfRectData SourceRect = SwfRectData.identity;
public ushort Id = 0;
public byte[] ARGB32 = new byte[0];
public ushort Redirect = 0;
public SwfRectData SourceRect = SwfRectData.identity;
public SwfRectIntData TrimmedRect = SwfRectIntData.identity;
}
[System.Serializable]
class SwfAssetData {
public float FrameRate = 0.0f;
public List<SwfSymbolData> Symbols = new List<SwfSymbolData>();
public List<SwfBitmapData> Bitmaps = new List<SwfBitmapData>();
public float FrameRate = 0.0f;
public List<SwfSymbolData> Symbols = new List<SwfSymbolData>();
public List<SwfBitmapData> Bitmaps = new List<SwfBitmapData>();
}
}

View File

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

View File

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

View File

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