/* * Common.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.Text; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; using System.Windows.Forms; namespace LipSync { /// /// LipSync共用の関数 /// public class Common { private static string m_log_file = ""; private static StreamWriter m_sw = null; private static SaveFileDialog s_dialog = null; public static Color CURVE_X = Color.Black; public static Color CURVE_Y = Color.White; public static Color CURVE_SCALE = Color.Orange; public static Color CURVE_ALPHA = Color.Red; public static Color CURVE_ROTATE = Color.Navy; /// /// ファイルダイアログのFilterに指定しようとしている文字列がエラーを起こさないかどうかを確かめます /// /// /// public static bool CheckFilterValidity( string filter ) { if ( s_dialog == null ) { s_dialog = new SaveFileDialog(); } try { s_dialog.Filter = filter; return true; } catch { return false; } } public static void DebugWriteLine( string s ) { #if DEBUG #if MONO Console.WriteLine( s ); System.Diagnostics.Trace.WriteLine( s ); System.Diagnostics.Debug.WriteLine( s ); #else //System.Diagnostics.Debug.WriteLine( s ); Console.WriteLine( s ); #endif #endif } public static Image GetThumbnailImage( Image image, int width, int height ) { Bitmap res = new Bitmap( width, height, PixelFormat.Format32bppArgb ); if ( image == null ) { return res; } int w = image.Width; int h = image.Height; float ASPECTO = (float)width / (float)height; float aspecto = (float)w / (float)h; float order = 1f; //拡大率 int top = 0; //描画位置y座標 int left = 0; //描画位置x座標 if ( ASPECTO > aspecto ) { // サムネイルのほうが横長 order = (float)height / (float)h; left = (int)(width - order * w) / 2; } else { // サムネイルのほうが縦長 order = (float)width / (float)w; top = (int)(height - order * h) / 2; } using ( Graphics g = Graphics.FromImage( res ) ) { g.Clear( Color.Transparent ); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage( image, left, top, w * order, h * order ); } return res; } /// /// 2つの整数の最大公約数を返します。 /// /// /// /// public static long GetGCD( long m, long n ) { if ( n > m ) { long a = n; n = m; m = a; } while ( true ) { if ( n == 0 ) { return m; } long quotient = m / n; long odd = m - n * quotient; if ( odd == 0 ) { return n; } m = n; n = odd; } } public static Point PointFromPointF( PointF point_f ) { return new Point( (int)point_f.X, (int)point_f.Y ); } public static Size SizeFromSizeF( SizeF size_f ) { return new Size( (int)size_f.Width, (int)size_f.Height ); } /// /// 画像から不透明領域を検出する。 /// /// /// public static Rectangle GetNonTransparentRegion( Bitmap bmp ) { if ( bmp.PixelFormat != PixelFormat.Format32bppArgb ) { return new Rectangle(); } BitmapData bmpdat = bmp.LockBits( new Rectangle( 0, 0, bmp.Width, bmp.Height ), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb ); int stride = bmpdat.Stride; int ymax = 0; int ymin = (bmp.Height - 1) * stride; int xmax = 0; int xmin = (bmp.Width - 1) * 4; const byte ZERO = 0; unsafe { byte* dat = (byte*)(void*)bmpdat.Scan0; int xend = bmp.Width * 4; int yend; for ( int x = 0; x < xend; x += 4 ) { // yminを決める yend = ymin;//ymin* stride; for ( int y = 0; y <= yend; y += stride ) { if ( dat[x + y + 3] != ZERO ) { //ymin = Math.Min( ymin, y / stride ); ymin = Math.Min( ymin, y ); break; } } // ymaxを決める yend = ymax;// ymax * stride; for ( int y = (bmp.Height - 1) * stride; y >= yend; y -= stride ) { if ( dat[x + y + 3] != ZERO ) { //ymax = Math.Max( ymax, y / stride ); ymax = Math.Max( ymax, y ); break; } } } yend = ymax;// ymax * stride; for ( int y = ymin; y <= yend; y += stride ) { // xminを決める for ( int x = 0; x < xmin; x += 4 ) { if ( dat[x + y + 3] != ZERO ) { //xmin = Math.Min( xmin, x / 4 ); xmin = Math.Min( xmin, x ); break; } } // xmaxを決める for ( int x = (bmp.Width - 1) * 4; x >= xmax; x -= 4 ) { if ( dat[x + y + 3] != ZERO ) { //xmax = Math.Max( xmax, x / 4 ); xmax = Math.Max( xmax, x ); break; } } } if ( xmax <= xmin || ymax <= ymin ) { xmin = 0; xmax = bmp.Width - 1; ymin = 0; ymax = bmp.Height - 1; } else { xmin = xmin / 4; xmax = xmax / 4; ymin = ymin / stride; ymax = ymax / stride; } } bmp.UnlockBits( bmpdat ); return new Rectangle( xmin, ymin, xmax - xmin + 1, ymax - ymin + 1 ); } public static void LogPush( Exception ex ) { LogPush( ex.Source + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace ); } public static void LogPush( string procedure, string message_type, string message ) { LogPush( procedure + ";" + message_type + ";" + message ); } static void LogPush( string message ) { if ( m_sw == null ) { m_log_file = Path.Combine( Application.StartupPath, "error.log" ); m_sw = new StreamWriter( m_log_file, true, Encoding.Unicode ); m_sw.WriteLine( "************************************************************************" ); m_sw.WriteLine( "Logger started : " + DateTime.Now.ToString() ); m_sw.WriteLine( "------------------------------------------------------------------------" ); } m_sw.WriteLine( DateTime.Now.ToString() + ";" + message ); m_sw.Flush(); } public static void LogClose() { if ( m_sw != null ) { m_sw.Close(); m_sw = null; } } /// /// 指定したパスのファイルからイメージを読み込みます /// /// イメージファイルへのパス /// public static Image ImageFromFile( string fpath ) { Bitmap result = null; if ( File.Exists( fpath ) ) { using ( FileStream fs = new FileStream( fpath, FileMode.Open, FileAccess.Read ) ) { Image temp = Image.FromStream( fs ); result = new Bitmap( temp.Width, temp.Height, PixelFormat.Format32bppArgb ); using ( Graphics g = Graphics.FromImage( result ) ) { g.DrawImage( temp, 0, 0, temp.Width, temp.Height ); } temp.Dispose(); } } return result; } } }