// Mixes two colors based on their alpha value, placing this over the other color. // Note: does not mix alpha values, simply sets the alpha to 1.0 public RGBA Mix(RGBA other) { this.R = this.R * this.A + other.R * other.A * (1.0 - this.A); this.G = this.G * this.A + other.G * other.A * (1.0 - this.A); this.B = this.B * this.A + other.B * other.A * (1.0 - this.A); this.A = 1.0; return this; }
// this is color from image, color is color to replace with alpha public RGBA ColorToAlpha(RGBA color) { RGBA x = new RGBA( ChannelToAlpha(this.R, color.R), ChannelToAlpha(this.G, color.G), ChannelToAlpha(this.B, color.B), this.A ); if (x.R > x.G) this.A = (x.R > x.B) ? x.R : x.B; else this.A = (x.G > x.B) ? x.G : x.B; if (this.A >= 0.0001) { this.R = (this.R - color.R) / this.A + color.R; this.G = (this.G - color.G) / this.A + color.G; this.B = (this.B - color.B) / this.A + color.B; this.A *= x.A; } return this; }
static int Main(string[] args) { if (args.Length != 3) { Console.WriteLine("You need to include the background image (PNG, GIF, JPEG, EXIG, or TIFF) file, a source directory (containing all the FirstUXRes animation files), and a destination directory on the command line."); return 1; } // Color to replace RGBA black = new RGBA(0.0, 0.0, 0.0, 1.0); // Open the background image Bitmap bkgrnd = null; try { bkgrnd = new Bitmap(args[0]); } catch (Exception ex) { Console.Error.WriteLine("There was a problem opening the background image '"+args[0]+"': "+ex.Message); return 1; } // Target height and width int width = bkgrnd.Width, height = bkgrnd.Height; // Open the directory DirectoryInfo dir = null; try { dir = new DirectoryInfo(args[1]); } catch (Exception ex) { Console.Error.WriteLine("There was a problem opening the directory '"+args[1]+"': "+ex.Message); return 1; } // Create/open destination directory String dest = args[2]; if (File.Exists(dest)) { Console.Error.WriteLine("The path '"+dest+"' is not a directory"); return 1; } else if (!Directory.Exists(dest)) { try { Directory.CreateDirectory(dest); } catch (Exception ex) { Console.Error.WriteLine("There was a problem creating the directory '"+dest+"': "+ex.Message); return 1; } } // Go through each file foreach (FileInfo fi in dir.GetFiles("*.bmp")) { String name = fi.FullName; String file = Path.GetFileName(name); try { // Open it Bitmap img = new Bitmap(name); if (img.Width != width || img.Height != height) { Console.WriteLine("Skipping '"+name+"' because it was the wrong size."); continue; } // Go through each pixel for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { // Get the foreground and background colors RGBA f = (RGBA)img.GetPixel(x, y); RGBA b = (RGBA)bkgrnd.GetPixel(x, y); // Convert to alpha, mix, and replace pixel img.SetPixel(x, y, (Color)f.ColorToAlpha(black).Mix(b)); } } img.Save(dest+"\\"+file, System.Drawing.Imaging.ImageFormat.Bmp); } catch (Exception ex) { Console.Error.WriteLine("There was a problem editing the image '"+file+"': "+ex.Message); } } return 0; }