1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108 |
- using System;
- using System.IO;
- using System.Text;
- using System.Collections;
- using System.Windows.Forms;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Drawing.Drawing2D;
- using System.Globalization;
- //////////////////////////////////////////////////////////////////////////////
- public class FastBitmap : IDisposable, ICloneable
- {
- internal Bitmap _bitmap;
- private BitmapData _bitmapData;
- public FastBitmap(Int32 width, Int32 height, PixelFormat fmt)
- {
- _bitmap = new Bitmap(width, height, fmt);
- }
- public FastBitmap(String filename)
- {
- _bitmap = new Bitmap(filename);
- }
- ~FastBitmap()
- {
- Dispose(false);
- }
- public void Dispose()
- {
- GC.SuppressFinalize(this);
- Dispose(true);
- }
- protected virtual void Dispose(Boolean disposing)
- {
- Unlock();
- if (disposing)
- {
- _bitmap.Dispose();
- }
- }
- private FastBitmap()
- {
- }
- public Object Clone()
- {
- FastBitmap clone = new FastBitmap();
- clone._bitmap = (Bitmap)_bitmap.Clone();
- return clone;
- }
- public Int32 Width
- {
- get { return _bitmap.Width; }
- }
- public Int32 Height
- {
- get { return _bitmap.Height; }
- }
- public void Lock()
- {
- _bitmapData = _bitmap.LockBits(
- new Rectangle(0, 0, _bitmap.Width, _bitmap.Height),
- ImageLockMode.ReadWrite,
- _bitmap.PixelFormat
- );
- }
- unsafe public Color GetPixel(Int32 x, Int32 y)
- {
- if (_bitmapData.PixelFormat == PixelFormat.Format32bppArgb)
- {
- Byte* b = (Byte*)_bitmapData.Scan0 + (y * _bitmapData.Stride) + (x * 4);
- return Color.FromArgb(*(b + 3), *(b + 2), *(b + 1), *b);
- }
- if (_bitmapData.PixelFormat == PixelFormat.Format24bppRgb)
- {
- Byte* b = (Byte*)_bitmapData.Scan0 + (y * _bitmapData.Stride) + (x * 3);
- return Color.FromArgb(*(b + 2), *(b + 1), *b);
- }
- return Color.Empty;
- }
- unsafe public void SetPixel(Int32 x, Int32 y, Color c)
- {
- if (_bitmapData.PixelFormat == PixelFormat.Format32bppArgb)
- {
- Byte* b = (Byte*)_bitmapData.Scan0 + (y * _bitmapData.Stride) + (x * 4);
- *b = c.B;
- *(b + 1) = c.G;
- *(b + 2) = c.R;
- *(b + 3) = c.A;
- }
- if (_bitmapData.PixelFormat == PixelFormat.Format24bppRgb)
- {
- Byte* b = (Byte*)_bitmapData.Scan0 + (y * _bitmapData.Stride) + (x * 3);
- *b = c.B;
- *(b + 1) = c.G;
- *(b + 2) = c.R;
- }
- }
- public void CopyTo(FastBitmap bitmap, Int32 destx, Int32 desty, Int32 srcx, Int32 srcy,
- Int32 width, Int32 height)
- {
- try
- {
- Lock();
- bitmap.Lock();
- for (Int32 y = 0; y < height; y++)
- {
- for (Int32 x = 0; x < width; x++)
- {
- Color c = GetPixel(srcx + x, srcy + y);
- bitmap.SetPixel(destx + x, desty + y, c);
- }
- }
- }
- finally
- {
- Unlock();
- bitmap.Unlock();
- }
- }
- public Byte GetIntensity(Int32 x, Int32 y)
- {
- Color c = GetPixel(x, y);
- return (Byte)((c.R * 0.30 + c.G * 0.59 + c.B * 0.11) + 0.5);
- }
- public void Unlock()
- {
- if (_bitmapData != null)
- {
- _bitmap.UnlockBits(_bitmapData);
- _bitmapData = null;
- }
- }
- public void Save(String filename, ImageFormat format)
- {
- _bitmap.Save(filename, format);
- }
- public void Save(String filename)
- {
- _bitmap.Save(filename);
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- class Layer : ICloneable
- {
- internal FastBitmap _bitmap;
- private FastBitmap _mask;
- public Double _opacity;
- private Int32 _offsetx, _offsety;
- public Layer(Int32 width, Int32 height)
- {
- _bitmap = new FastBitmap(width, height, PixelFormat.Format32bppArgb);
- Clear(Color.Transparent);
- _opacity = 1.0;
- }
- public Layer(FastBitmap bitmap)
- {
- _bitmap = bitmap;
- _opacity = 1.0;
- }
- public Double Opacity
- {
- get { return _opacity; }
- set { _opacity = value; }
- }
- public FastBitmap Bitmap
- {
- get { return _bitmap; }
- }
- public FastBitmap Mask
- {
- get { return _mask; }
- set { _mask = value; }
- }
- public Int32 OffsetX
- {
- get { return _offsetx; }
- set { _offsetx = value; }
- }
- public Int32 OffsetY
- {
- get { return _offsety; }
- set { _offsety = value; }
- }
- public Object Clone()
- {
- Layer clone = new Layer(_bitmap.Width, _bitmap.Height);
- clone._bitmap = (FastBitmap)_bitmap.Clone();
- return clone;
- }
- public void Clear(Color c)
- {
- _bitmap.Lock();
- for (Int32 y = 0; y < _bitmap.Height; y++)
- for (Int32 x = 0; x < _bitmap.Width; x++)
- _bitmap.SetPixel(x, y, c);
- _bitmap.Unlock();
- }
- public void DrawText(Int32 x, Int32 y, String text, Font font,
- Brush brush)
- {
- Graphics g = Graphics.FromImage(_bitmap._bitmap);
- g.DrawString(text, font, brush, x, y, StringFormat.GenericTypographic);
- g.Dispose();
- }
- public void FillRectangle(Int32 x, Int32 y, Int32 width,
- Int32 height, Brush brush)
- {
- Graphics g = Graphics.FromImage(_bitmap._bitmap);
- g.FillRectangle(brush, x, y, width, height);
- g.Dispose();
- }
- public Color GetPixel(Int32 x, Int32 y)
- {
- return _bitmap.GetPixel(x, y);
- }
- public void Invert()
- {
- _bitmap.Lock();
- for (Int32 y = 0; y < _bitmap.Height; y++)
- {
- for (Int32 x = 0; x < _bitmap.Width; x++)
- {
- Color c = _bitmap.GetPixel(x, y);
- _bitmap.SetPixel(x, y, Color.FromArgb(c.A,
- 255 - c.R, 255 - c.G, 255 - c.B));
- }
- }
- _bitmap.Unlock();
- }
- private Single Gauss(Single x, Single middle, Single width)
- {
- if (width == 0)
- return 1F;
- Double t = -(1.0 / width) * ((middle - x) * (middle - x));
- return (Single)Math.Pow(/*Math.E*/1.5, t);
- }
- public void Blur(Int32 horz, Int32 vert)
- {
- Single weightsum;
- Single[] weights;
- FastBitmap t = (FastBitmap)_bitmap.Clone();
- _bitmap.Lock();
- t.Lock();
- // horizontal blur
- weights = new Single[horz * 2 + 1];
- for (Int32 i = 0; i < horz * 2 + 1; i++)
- {
- Single y = Gauss(-horz + i, 0, horz);
- weights[i] = y;
- }
- for (Int32 row = 0; row < _bitmap.Height; row++)
- {
- for (Int32 col = 0; col < _bitmap.Width; col++)
- {
- Double r = 0;
- Double g = 0;
- Double b = 0;
- Double a = 0;
- weightsum = 0;
- for (Int32 i = 0; i < horz * 2 + 1; i++)
- {
- Int32 x = col - horz + i;
- if (x < 0)
- {
- i += -x;
- x = 0;
- }
- if (x > _bitmap.Width - 1)
- break;
- Color c = _bitmap.GetPixel(x, row);
- r += c.R * weights[i] / 255.0 * c.A;
- g += c.G * weights[i] / 255.0 * c.A;
- b += c.B * weights[i] / 255.0 * c.A;
- a += c.A * weights[i];
- weightsum += weights[i];
- }
- r /= weightsum;
- g /= weightsum;
- b /= weightsum;
- a /= weightsum;
- Byte br = (Byte)Math.Round(r);
- Byte bg = (Byte)Math.Round(g);
- Byte bb = (Byte)Math.Round(b);
- Byte ba = (Byte)Math.Round(a);
- if (br > 255) br = 255;
- if (bg > 255) bg = 255;
- if (bb > 255) bb = 255;
- if (ba > 255) ba = 255;
- t.SetPixel(col, row, Color.FromArgb(ba, br, bg, bb));
- }
- }
- // vertical blur
- weights = new Single[vert * 2 + 1];
- for (Int32 i = 0; i < vert * 2 + 1; i++)
- {
- Single y = Gauss(-vert + i, 0, vert);
- weights[i] = y;
- }
- for (Int32 col = 0; col < _bitmap.Width; col++)
- {
- for (Int32 row = 0; row < _bitmap.Height; row++)
- {
- Double r = 0;
- Double g = 0;
- Double b = 0;
- Double a = 0;
- weightsum = 0;
- for (Int32 i = 0; i < vert * 2 + 1; i++)
- {
- Int32 y = row - vert + i;
- if (y < 0)
- {
- i += -y;
- y = 0;
- }
- if (y > _bitmap.Height - 1)
- break;
- Color c = t.GetPixel(col, y);
- r += c.R * weights[i] / 255.0 * c.A;
- g += c.G * weights[i] / 255.0 * c.A;
- b += c.B * weights[i] / 255.0 * c.A;
- a += c.A * weights[i];
- weightsum += weights[i];
- }
- r /= weightsum;
- g /= weightsum;
- b /= weightsum;
- a /= weightsum;
- Byte br = (Byte)Math.Round(r);
- Byte bg = (Byte)Math.Round(g);
- Byte bb = (Byte)Math.Round(b);
- Byte ba = (Byte)Math.Round(a);
- if (br > 255) br = 255;
- if (bg > 255) bg = 255;
- if (bb > 255) bb = 255;
- if (ba > 255) ba = 255;
- _bitmap.SetPixel(col, row, Color.FromArgb(ba, br, bg, bb));
- }
- }
- t.Dispose(); // will unlock
- _bitmap.Unlock();
- }
- private Byte GetBumpMapPixel(FastBitmap bmp, Int32 x, Int32 y)
- {
- // create a single number from R, G and B values at point (x, y)
- // if point (x, y) lays outside the bitmap, GetBumpMapPixel()
- // returns the closest pixel within the bitmap
- if (x < 0)
- x = 0;
- if (x > _bitmap.Width - 1)
- x = _bitmap.Width - 1;
- if (y < 0)
- y = 0;
- if (y > _bitmap.Height - 1)
- y = _bitmap.Height - 1;
- return bmp.GetIntensity(x, y);
- }
- public void BumpMap(Layer bumpmap, Int32 azimuth, Int32 elevation,
- Int32 bevelwidth, Boolean lightzalways1)
- {
- bumpmap._bitmap.Lock();
- _bitmap.Lock();
- for (Int32 row = 0; row < _bitmap.Height; row++)
- {
- for (Int32 col = 0; col < _bitmap.Width; col++)
- {
- // calculate normal for point (col, row)
- // this is an approximation of the derivative
- // I personally haven't figured out why it's
- // the way it is
- // normal_z is constant, I think this means
- // the longer the vector is, the more it lays
- // in the xy plane
- Byte[] x = new Byte[6];
- x[0] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row - 1);
- x[1] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row - 0);
- x[2] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row + 1);
- x[3] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row - 1);
- x[4] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row - 0);
- x[5] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row + 1);
- Single normal_x = x[0] + x[1] + x[2] - x[3] - x[4] - x[5];
- x[0] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row + 1);
- x[1] = GetBumpMapPixel(bumpmap._bitmap, col - 0, row + 1);
- x[2] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row + 1);
- x[3] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row - 1);
- x[4] = GetBumpMapPixel(bumpmap._bitmap, col - 0, row - 1);
- x[5] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row - 1);
- Single normal_y = x[0] + x[1] + x[2] - x[3] - x[4] - x[5];
- Single normal_z = (6F * 255F) / bevelwidth;
- Single length = (Single)Math.Sqrt(
- normal_x * normal_x +
- normal_y * normal_y +
- normal_z * normal_z);
- if (length != 0)
- {
- normal_x /= length;
- normal_y /= length;
- normal_z /= length;
- }
- // convert to radians
- Double azimuth_rad = azimuth / 180.0 * Math.PI;
- Double elevation_rad = elevation / 180.0 * Math.PI;
- // light vector -- this is the location of the light
- // source but it also serves as the direction with
- // origin <0, 0, 0>
- // the formulas to calculate x, y and z are those to
- // rotate a point in 3D space
- // if lightzalways1 is true, light_z is set to 1
- // because we want full color intensity for that pixel;
- // if we set light_z to (Single)Math.Sin(elevation_rad),
- // which is the correct way to calculate light_z, the
- // color is more dark, but when we ignore light_z, the
- // light source is straight above the pixel and
- // therefore sin(elevation_rad) is always 1
- Single light_x = (Single)(Math.Cos(azimuth_rad) *
- Math.Cos(elevation_rad));
- Single light_y = (Single)(Math.Sin(azimuth_rad) *
- Math.Cos(elevation_rad));
- Single light_z = 1F;
- if (!lightzalways1)
- light_z = (Single)Math.Sin(elevation_rad);
- // the normal and light vector are unit vectors, so
- // taking the dot product of these two yields the
- // cosine of the angle between them
- Single cos_light_normal = 0;
- cos_light_normal += normal_x * light_x;
- cos_light_normal += normal_y * light_y;
- cos_light_normal += normal_z * light_z;
- // get pixel (col, row) of this layer, calculate color
- // and set pixel back with new color
- Color c = _bitmap.GetPixel(col, row);
- Single r = c.R;
- Single g = c.G;
- Single b = c.B;
- r *= cos_light_normal;
- g *= cos_light_normal;
- b *= cos_light_normal;
- Byte red = (Byte)Math.Min(Math.Round(r), 255);
- Byte green = (Byte)Math.Min(Math.Round(g), 255);
- Byte blue = (Byte)Math.Min(Math.Round(b), 255);
- _bitmap.SetPixel(col, row, Color.FromArgb(red, green, blue));
- }
- }
- _bitmap.Unlock();
- bumpmap._bitmap.Unlock();
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- class Layers
- {
- LayeredImage _image;
- ArrayList _layers = new ArrayList();
- public Layers(LayeredImage image)
- {
- _image = image;
- }
- public Int32 Count
- {
- get { return _layers.Count; }
- }
- public Layer Add()
- {
- Layer layer = new Layer(_image.Width, _image.Height);
- _layers.Add(layer);
- return layer;
- }
- public Layer Add(FastBitmap bitmap)
- {
- Layer layer = new Layer(bitmap);
- _layers.Add(layer);
- return layer;
- }
- public Layer Add(Int32 width, Int32 height)
- {
- Layer layer = new Layer(width, height);
- _layers.Add(layer);
- return layer;
- }
- public Layer Copy(Layer layer)
- {
- Layer copy = (Layer)layer.Clone();
- _layers.Add(copy);
- return copy;
- }
- public Layer this[Int32 i]
- {
- get { return (Layer)_layers[i]; }
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- class LayeredImage
- {
- Int32 _width, _height;
- Bitmap _checkerboard;
- Layers _layers;
- public LayeredImage(Int32 width, Int32 height)
- {
- _width = width;
- _height = height;
- _layers = new Layers(this);
- // checker board brush
- _checkerboard = new Bitmap(32, 32, PixelFormat.Format24bppRgb);
- Color darkgray = Color.FromArgb(102, 102, 102);
- Color lightgray = Color.FromArgb(153, 153, 153);
- for (Int32 i = 0; i < 32; i++)
- {
- for (Int32 j = 0; j < 32; j++)
- {
- if ((i < 16 && j < 16) || (i >= 16 && j >= 16))
- _checkerboard.SetPixel(j, i, lightgray);
- else
- _checkerboard.SetPixel(j, i, darkgray);
- }
- }
- // background layer
- Layer bglayer = _layers.Add();
- Graphics g = Graphics.FromImage(bglayer._bitmap._bitmap);
- TextureBrush brush = new TextureBrush(_checkerboard);
- g.FillRectangle(brush, 0, 0, _width, _height);
- brush.Dispose();
- g.Dispose();
- }
- public Int32 Width
- {
- get { return _width; }
- }
- public Int32 Height
- {
- get { return _height; }
- }
- public Layers Layers
- {
- get { return _layers; }
- }
- internal FastBitmap Flatten()
- {
- // create a bitmap for result image
- FastBitmap final = new FastBitmap(_width, _height,
- PixelFormat.Format24bppRgb);
- // lock all bitmaps
- final.Lock();
- for (Int32 i = 0; i < _layers.Count; i++)
- {
- Layer l = _layers[i];
- l._bitmap.Lock();
- if (l.Mask != null)
- l.Mask.Lock();
- }
- // calculate colors of flattened image
- // 1. take offsetx, offsety into consideration
- // 2. calculate alpha of color (alpha, opacity, mask)
- // 3. mix colors of current layer and layer below
- for (Int32 y = 0; y < _height; y++)
- {
- for (Int32 x = 0; x < _width; x++)
- {
- Color c0 = _layers[0]._bitmap.GetPixel(x, y);
- for (Int32 i = 1; i < _layers.Count; i++)
- {
- Layer layer = _layers[i];
- Color c1 = Color.Transparent;
- if (x >= layer.OffsetX &&
- x <= layer.OffsetX + layer._bitmap.Width - 1 &&
- y >= layer.OffsetY &&
- y <= layer.OffsetY + layer._bitmap.Height - 1)
- {
- c1 = layer._bitmap.GetPixel(x - layer.OffsetX,
- y - layer.OffsetY);
- }
- if (c1.A == 255 && layer.Opacity == 1.0 &&
- layer.Mask == null)
- {
- c0 = c1;
- }
- else
- {
- Double tr, tg, tb, a;
- a = c1.A / 255.0 * layer.Opacity;
- if (layer.Mask != null)
- {
- a *= layer.Mask.GetIntensity(x, y) / 255.0;
- }
- tr = c1.R * a + c0.R * (1.0 - a);
- tg = c1.G * a + c0.G * (1.0 - a);
- tb = c1.B * a + c0.B * (1.0 - a);
- tr = Math.Round(tr);
- tg = Math.Round(tg);
- tb = Math.Round(tb);
- tr = Math.Min(tr, 255);
- tg = Math.Min(tg, 255);
- tb = Math.Min(tb, 255);
- c0 = Color.FromArgb((Byte)tr, (Byte)tg, (Byte)tb);
- }
- }
- final.SetPixel(x, y, c0);
- }
- }
- // unlock all bitmaps
- for (Int32 i = 0; i < _layers.Count; i++)
- {
- Layer l = _layers[i];
- l._bitmap.Unlock();
- if (l.Mask != null)
- l.Mask.Unlock();
- }
- final.Unlock();
- return final;
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- class Shadow
- {
- static void PrintUsage()
- {
- Console.WriteLine("Shadow 1.0 for .NET http://home.tiscali.be/zoetrope/");
- Console.WriteLine("Syntax is: SHADOW [ options ] inpfile [ outfile ]");
- Console.WriteLine(" -s:xx Shadow width (default = 8)");
- Console.WriteLine(" -b:xx Border width (default = 0)");
- Console.WriteLine(" -m:xx Margin (default = 8)");
- Console.WriteLine(" -r:x Shadow direction (default = 0)");
- Console.WriteLine(" -t:N Shadow transparency (default = 0.0)");
- Console.WriteLine(" -a:xxxxxx Background color (default = FFFFFF)");
- Console.WriteLine(" -c:xxxxxx Shadow color (default = 000000)");
- Console.WriteLine(" -d:xxxxxx Border color (default = 000000)");
- Console.WriteLine(" -n No soft shadow");
- }
- private static Color HexColorToColor(String s)
- {
- if (s.Length != 6)
- return Color.Empty;
- UInt32 r, g, b;
- r = g = b = 0;
- for (Int32 i = 0; i < 6; i++)
- {
- Int32 n = "0123456789ABCDEF".IndexOf(Char.ToUpper(s[i]));
- if (n == -1)
- return Color.Empty;
- UInt32 x = (UInt32)n;
- switch (i)
- {
- case 0:
- r |= x << 4;
- break;
- case 1:
- r |= x;
- break;
- case 2:
- g |= x << 4;
- break;
- case 3:
- g |= x;
- break;
- case 4:
- b |= x << 4;
- break;
- case 5:
- b |= x;
- break;
- }
- }
- return Color.FromArgb((Byte)r, (Byte)g, (Byte)b);
- }
- private static Boolean GetArgParam(String arg, out Int32 num)
- {
- num = 0;
- if (arg.Length < 4)
- return false;
- String[] str = arg.Split(new Char[] { ':' }, 2);
- if (str.Length != 2)
- return false;
- try
- {
- num = Convert.ToInt32(str[1]);
- return true;
- }
- catch
- {
- // catch all exceptions Convert.ToInt32() can throw;
- // no other exceptions can be thrown
- return false;
- }
- }
- private static Boolean GetArgParam(String arg, out Double num)
- {
- num = 0.0;
- if (arg.Length < 4)
- return false;
- String[] str = arg.Split(new Char[] { ':' }, 2);
- if (str.Length != 2)
- return false;
- try
- {
- num = Convert.ToDouble(str[1], CultureInfo.InvariantCulture);
- return true;
- }
- catch
- {
- // catch all exceptions Convert.ToInt32() can throw;
- // no other exceptions can be thrown
- return false;
- }
- }
- private static Boolean GetArgParam(String arg, out Color col)
- {
- col = Color.Empty;
- if (arg.Length != 9)
- return false;
- String[] str = arg.Split(new Char[] { ':' }, 2);
- if (str.Length != 2)
- return false;
- col = HexColorToColor(str[1]);
- return (col != Color.Empty);
- }
- static void Main(String[] args)
- {
- if (args.Length == 0)
- {
- PrintUsage();
- return;
- }
- Int32 shadowwidth = 8;
- Int32 borderwidth = 0;
- Int32 margin = shadowwidth;
- Int32 shadowdir = 0;
- Double shadowtrans = 0.0;
- Color bkcolor = Color.FromArgb(255, 255, 255);
- Color shadowcolor = Color.FromArgb(0, 0, 0);
- Color bordercolor = Color.FromArgb(0, 0, 0);
- Boolean softshadow = true;
- String inputfile = "";
- String outputfile = "";
- for (Int32 i = 0; i < args.Length; i++)
- {
- if (args[i].Length == 0)
- {
- PrintUsage();
- return;
- }
- if (args[i][0] == '-')
- {
- Boolean b;
- switch (args[i][1])
- {
- case 's':
- b = GetArgParam(args[i], out shadowwidth);
- if (!b || (shadowwidth < 0 || shadowwidth > 99))
- {
- Console.WriteLine("Error: Incorrect command line option: -s");
- return;
- }
- break;
- case 'b':
- b = GetArgParam(args[i], out borderwidth);
- if (!b || (borderwidth < 0 || borderwidth > 99))
- {
- Console.WriteLine("Error: Incorrect command line option: -b");
- return;
- }
- break;
- case 'm':
- b = GetArgParam(args[i], out margin);
- if (!b || (margin < 0 || margin > 99))
- {
- Console.WriteLine("Error: Incorrect command line option: -b");
- return;
- }
- break;
- case 'r':
- b = GetArgParam(args[i], out shadowdir);
- if (!b || (shadowdir < 0 || shadowdir > 3))
- {
- Console.WriteLine("Error: Incorrect command line option: -r");
- return;
- }
- break;
- case 't':
- b = GetArgParam(args[i], out shadowtrans);
- if (!b || (shadowtrans < 0.0 || shadowtrans > 1.0))
- {
- Console.WriteLine("Error: Incorrect command line option: -t");
- return;
- }
- break;
- case 'a':
- b = GetArgParam(args[i], out bkcolor);
- if (!b)
- {
- Console.WriteLine("Error: Incorrect command line option: -a");
- return;
- }
- break;
- case 'c':
- b = GetArgParam(args[i], out shadowcolor);
- if (!b)
- {
- Console.WriteLine("Error: Incorrect command line option: -c");
- return;
- }
- break;
- case 'd':
- b = GetArgParam(args[i], out bordercolor);
- if (!b)
- {
- Console.WriteLine("Error: Incorrect command line option: -d");
- return;
- }
- break;
- case 'n':
- softshadow = false;
- break;
- default:
- Console.WriteLine("Fatal: Illegal option: {0}", args[i]);
- return;
- }
- }
- else
- {
- // must be a file name
- if (inputfile == "")
- inputfile = args[i];
- else if (outputfile == "")
- outputfile = args[i];
- // ignore other file names
- }
- }
- if (inputfile == "")
- {
- Console.WriteLine("Error: No file names given");
- return;
- }
- FastBitmap tmp, bmp;
- // try-catch doesn't work like it should
- if (File.Exists(inputfile))
- {
- tmp = new FastBitmap(inputfile);
- }
- else
- {
- Console.WriteLine("Error: Could not find file '{0}'", inputfile);
- return;
- }
- bmp = new FastBitmap(tmp.Width + borderwidth * 2, tmp.Height + borderwidth * 2,
- PixelFormat.Format32bppArgb);
- // add border if necessary
- if (borderwidth > 0)
- {
- SolidBrush br = new SolidBrush(bordercolor);
- Graphics g = Graphics.FromImage(bmp._bitmap);
- g.FillRectangle(br, 0, 0, borderwidth * 2 + tmp.Width, borderwidth * 2 + tmp.Height);
- g.Dispose();
- br.Dispose();
- }
- tmp.CopyTo(bmp, borderwidth, borderwidth, 0, 0, tmp.Width, tmp.Height);
- tmp.Dispose();
- // create image
- Int32 width = bmp.Width + shadowwidth + margin * 2;
- Int32 height = bmp.Height + shadowwidth + margin * 2;
- LayeredImage image = new LayeredImage(width, height);
- Int32 shadowx = 0, shadowy = 0, imgx = 0, imgy = 0;
- if (softshadow)
- {
- switch (shadowdir)
- {
- case 0:
- shadowx = margin - shadowwidth / 2;
- shadowy = margin - shadowwidth / 2;
- imgx = margin;
- imgy = margin;
- break;
- case 1:
- shadowx = margin + shadowwidth - 3 * (shadowwidth / 2);
- shadowy = margin - shadowwidth / 2;
- imgx = margin + shadowwidth;
- imgy = margin;
- break;
- case 2:
- shadowx = margin + shadowwidth - 3 * (shadowwidth / 2);
- shadowy = margin + shadowwidth - 3 * (shadowwidth / 2);
- imgx = margin + shadowwidth;
- imgy = margin + shadowwidth;
- break;
- case 3:
- shadowx = margin - shadowwidth / 2;
- shadowy = margin + shadowwidth - 3 * (shadowwidth / 2);
- imgx = margin;
- imgy = margin + shadowwidth;
- break;
- }
- }
- else
- {
- switch (shadowdir)
- {
- case 0:
- shadowx = margin;
- shadowy = margin;
- imgx = margin;
- imgy = margin;
- break;
- case 1:
- shadowx = margin - shadowwidth;
- shadowy = margin;
- imgx = margin + shadowwidth;
- imgy = margin;
- break;
- case 2:
- shadowx = margin - shadowwidth;
- shadowy = margin - shadowwidth;
- imgx = margin + shadowwidth;
- imgy = margin + shadowwidth;
- break;
- case 3:
- shadowx = margin;
- shadowy = margin - shadowwidth;
- imgx = margin;
- imgy = margin + shadowwidth;
- break;
- }
- }
- // background
- Layer bg = image.Layers.Add();
- bg.Clear(bkcolor);
- // shadow -- layer must be larger because of blur
- Layer shadow = image.Layers.Add(width + shadowwidth, height + shadowwidth);
- SolidBrush brush = new SolidBrush(shadowcolor);
- shadow.FillRectangle(shadowwidth, shadowwidth, bmp.Width, bmp.Height, brush);
- if (softshadow)
- shadow.Blur(shadowwidth, shadowwidth);
- brush.Dispose();
- shadow.OffsetX = shadowx;
- shadow.OffsetY = shadowy;
- shadow.Opacity = 1.0 - shadowtrans;
- // image
- Layer img = image.Layers.Add(bmp);
- img.OffsetX = imgx;
- img.OffsetY = imgy;
- // result
- FastBitmap result = image.Flatten();
- // save
- String filename = outputfile != "" ? outputfile : inputfile;
- String ext = Path.GetExtension(filename);
- if (ext == "")
- ext = ".bmp";
- ext = ext.ToLower();
- ImageFormat imgf = ImageFormat.Bmp;
- switch (ext)
- {
- case ".bmp":
- ext = ".bmp";
- imgf = ImageFormat.Bmp;
- break;
- case ".jpg":
- ext = ".jpg";
- imgf = ImageFormat.Jpeg;
- break;
- case ".jpeg":
- ext = ".jpeg";
- imgf = ImageFormat.Jpeg;
- break;
- case ".png":
- ext = ".png";
- imgf = ImageFormat.Png;
- break;
- case ".gif":
- ext = ".gif";
- imgf = ImageFormat.Gif;
- break;
- default:
- ext = ".bmp";
- imgf = ImageFormat.Bmp;
- break;
- }
- filename = Path.GetFileNameWithoutExtension(filename);
- result.Save(filename + ext, imgf);
- }
- }
|