/* * Character.cs * Copyright (c) 2007-2009 kbinani * * This file is part of LipSync. * * LipSync is free software; you can redistribute it and/or * modify it under the terms of the BSD License. * * LipSync is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; namespace LipSync { public enum CharacterType { def, plugin } [Serializable] public class Character : IDisposable { public CharacterType type; string m_Name; public PluginConfig m_pluginConfig; public Size m_plugin_drawarea; [Obsolete] public Image Base; [Obsolete] public Image a; [Obsolete] public Image aa; [Obsolete] public Image i; [Obsolete] public Image u; [Obsolete] public Image e; [Obsolete] public Image o; [Obsolete] public Image xo; [Obsolete] public Image nn; public List Images; [NonSerialized] private Bitmap m_cache = null; [NonSerialized] private string m_cache_draw = ""; [OptionalField] public string version;//setDefaultで変更するので、readonlyにしたいけどできん [OptionalField] public Size m_size; [OptionalField] public Bitmap m_preview = null; [NonSerialized] bool internal_operation = false; [OnDeserializing] private void onDeserializing( StreamingContext sc ) { version = "0"; m_size = new Size( 0, 0 ); } [OnSerialized] private void onSerialized( StreamingContext sc ) { if ( m_size.Equals( new Size( 0, 0 ) ) ) { foreach ( ImageEntry img in Images ) { if ( img.title == "base" ) { if ( img.Image != null ) { m_size = new Size( img.Image.Width, img.Image.Height ); break; } } } } } [OnDeserialized] private void onDeserialized( StreamingContext sc ){ // 古いバージョンの*.lseとの互換性を保つため。 // base, a, ..., nnのデータをImagesに移動させる if ( nn != null ) { Images.Insert( 0, new ImageEntry( "nn", nn, "口", false ) ); nn.Dispose(); } if ( xo != null ) { Images.Insert( 0, new ImageEntry( "xo", xo, "口", false ) ); xo.Dispose(); } if ( o != null ) { Images.Insert( 0, new ImageEntry( "o", o, "口", false ) ); o.Dispose(); } if ( e != null ) { Images.Insert( 0, new ImageEntry( "e", e, "口", false ) ); e.Dispose(); } if ( u != null ) { Images.Insert( 0, new ImageEntry( "u", u, "口", false ) ); u.Dispose(); } if ( i != null ) { Images.Insert( 0, new ImageEntry( "i", i, "口", false ) ); i.Dispose(); } if ( aa != null ) { Images.Insert( 0, new ImageEntry( "aa", aa, "口", false ) ); aa.Dispose(); } if ( a != null ) { Images.Insert( 0, new ImageEntry( "a", a, "口", false ) ); a.Dispose(); } if ( Base != null ) { Images.Insert( 0, new ImageEntry( "base", Base, "本体", true ) ); Base.Dispose(); } if ( version == "0" ) { for ( int k = 0; k < Images.Count; k++ ) { if ( Images[k].title == "base" ) { Images[k].IsDefault = true; m_size = Images[k].Image.Size; version = "2"; } } } if ( m_size.Width <= 0 || m_size.Height <= 0 ) { int max_x = 0; int max_y = 0; foreach ( ImageEntry img in Images ) { if ( img.Image != null ) { max_x = Math.Max( max_x, img.Image.Width + img.XOffset ); max_y = Math.Max( max_y, img.Image.Height + img.YOffset ); } } m_size = new Size( max_x, max_y ); } } public void Dispose() { m_Name = null; m_pluginConfig = null; if ( Base != null ) { Base.Dispose(); } if ( a != null ) { a.Dispose(); } if ( aa != null ) { aa.Dispose(); } if ( i != null ) { i.Dispose(); } if ( u != null ) { u.Dispose(); } if ( e != null ) { e.Dispose(); } if ( o != null ) { o.Dispose(); } if ( xo != null ) { xo.Dispose(); } if ( nn != null ) { nn.Dispose(); } Images.Clear(); } public void Write( Stream stream ) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize( stream, this ); } public string GetMD5() { System.Security.Cryptography.MD5CryptoServiceProvider mcsp = new System.Security.Cryptography.MD5CryptoServiceProvider(); using ( MemoryStream ms = new MemoryStream() ) { this.Write( ms ); byte[] dat = mcsp.ComputeHash( ms ); string res = ""; foreach ( byte b in dat ) { res += b.ToString( "x2" ); } return res; } return ""; } public static Character FromFile( Stream stream ) { Character result = null; BinaryFormatter bf = new BinaryFormatter(); result = (Character)bf.Deserialize( stream ); bf = null; return result; } public static Character FromFile( string filepath ) { Character result = null; if ( File.Exists( filepath ) ) { using ( FileStream fs = new FileStream( filepath, FileMode.Open ) ) { result = FromFile( fs ); } } return result; } public int Width { get { return m_size.Width; } } public int Height { get { return m_size.Height; } } public string Name { get { return m_Name; } set { m_Name = value; } } public Bitmap DefaultFace { get { string type = ""; foreach ( ImageEntry img in this.Images ) { if ( img.IsDefault ) { type += img.title + "\n"; } } Bitmap res = Face( type ); #if DEBUG if ( res == null ) { Common.DebugWriteLine( "Character.DefaultFace.get(); res==null" ); Common.DebugWriteLine( " Width=" + Width ); Common.DebugWriteLine( " Height=" + Height ); Common.DebugWriteLine( " type=" + type ); } #endif return res; } } public Bitmap Face( string type ) { if ( Width <= 0 || Height <= 0 ) { return null; } if ( m_cache != null ) { if ( m_cache_draw == type ) { return (Bitmap)m_cache.Clone(); } } Bitmap bmp = new Bitmap( Width, Height ); string[] spl = type.Split( "\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries ); using ( Graphics g = Graphics.FromImage( bmp ) ) { //Image drawing; for ( int i = 0; i < spl.Length; i++ ) { for ( int index = 0; index < Images.Count; index++ ) { if ( Images[index].title == spl[i] ) { //drawing = Images[index].image; Images[index].DrawTo( g ); break; } } } } m_cache_draw = type; if ( m_cache != null ) { m_cache.Dispose(); } m_cache = (Bitmap)bmp.Clone(); return bmp; } } }