/*
* 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;
}
}
}