static void Main(string[] args) { DDSFile dds = DDSFile.LoadFile(args[0]); int w = dds.Width; int h = dds.Height; int halfW = w / 2; int halfH = h / 2; if (dds.BitsPerPixel != 32) { Console.WriteLine("Error: input file must be 32-bits per pixel"); } DDSFile destDDS = new DDSFile32(w * 2, h * 2); // copy the various parts of the source to pad all edges destDDS.Copy(dds, halfW, halfH, halfW, halfH, 0, 0); destDDS.Copy(dds, 0, halfH, w, halfH, halfW, 0); destDDS.Copy(dds, 0, halfH, halfW, halfH, w + halfW, 0); destDDS.Copy(dds, halfW, 0, halfW, h, 0, halfH); destDDS.Copy(dds, 0, 0, w, h, halfW, halfH); destDDS.Copy(dds, 0, 0, halfW, h, w + halfW, halfH); destDDS.Copy(dds, halfW, 0, halfW, halfH, 0, h + halfH); destDDS.Copy(dds, 0, 0, w, halfH, halfW, h + halfH); destDDS.Copy(dds, 0, 0, halfW, halfH, w + halfW, h + halfH); // save the padded tile destDDS.Save(args[1]); DDSFile preview = new DDSFile32(halfW, halfH); for (int y = 0; y < halfH; y++) { for (int x = 0; x < halfW; x++) { uint p0 = dds.GetPixel(x * 2, y * 2); uint p1 = dds.GetPixel(x * 2 + 1, y * 2); uint p2 = dds.GetPixel(x * 2, y * 2 + 1); uint p3 = dds.GetPixel(x * 2 + 1, y * 2 + 1); uint r = ((p0 >> 16) & 0xff) + ((p1 >> 16) & 0xff) + ((p2 >> 16) & 0xff) + ((p3 >> 16) & 0xff); uint g = ((p0 >> 8) & 0xff) + ((p1 >> 8) & 0xff) + ((p2 >> 8) & 0xff) + ((p3 >> 8) & 0xff); uint b = ((p0 >> 0) & 0xff) + ((p1 >> 0) & 0xff) + ((p2 >> 0) & 0xff) + ((p3 >> 0) & 0xff); uint a = ((p0 >> 24) & 0xff) + ((p1 >> 24) & 0xff) + ((p2 >> 24) & 0xff) + ((p3 >> 24) & 0xff); uint high = r; uint highCol = 0xffffffff; if (g > high) { high = g; highCol = 0xff000000; } if (b > high) { high = b; highCol = 0xffaaaaaa; } if (a > high) { high = g; highCol = 0xff555555; } preview.SetPixel(x, y, highCol); } } preview.Save(args[2]); }
static void DumpPixel(DDSFile dds, int x, int y) { Console.WriteLine("Pixel({0}, {1}) : 0x{2:x})", x, y, dds.GetPixel(x, y)); }
public void FillTile(DDSFile ddsDest) { for (int y = 0; y < dds.Height; y++) { for (int x = 0; x < dds.Width; x++) { HSVColor hsv = HSVColor.FromRGB(dds.GetPixel(x, y)); float[] distances = km.DistanceToCenters(hsv); int nearest, second; float nearestWeight; if (distances[0] < distances[1]) { nearest = 0; second = 1; } else { nearest = 1; second = 0; } if (distances[2] < distances[nearest]) { second = nearest; nearest = 2; } else if (distances[2] < distances[second]) { second = 2; } if (distances[3] < distances[nearest]) { second = nearest; nearest = 3; } else if (distances[3] < distances[second]) { second = 3; } // only weight between the two colors if the current point is nearer to each of them // than they are to each other. otherwise just weight to neartest. if (km.CenterDistances[nearest, second] < distances[second]) { nearestWeight = 1.0f; } else { nearestWeight = distances[second] / (distances[nearest] + distances[second]); } // init color components int[] components = new int[4]; components[0] = 0; components[1] = 0; components[2] = 0; components[3] = 0; nearest = kmColorMap[nearest]; second = kmColorMap[second]; components[nearest] = (int)(hsv.V * colors[nearest].VMult * 255 * nearestWeight); components[second] = (int)(hsv.V * colors[second].VMult * 255 * (1.0f - nearestWeight)); Color c = Color.FromArgb(components[3], components[0], components[1], components[2]); int index = kmColorMap[km.ClosestIndex(hsv)]; ddsDest.SetColor(x, y, c); } } }
public TileMaker(string filename, int numColors) { dds = DDSFile.LoadFile(filename); int numPixels = dds.Width * dds.Height; HSVColor[] pixels = new HSVColor[numPixels]; // create the array of colors in this image int offset = 0; for (int y = 0; y < dds.Height; y++) { for (int x = 0; x < dds.Width; x++) { pixels[offset] = HSVColor.FromRGB(dds.GetPixel(x, y)); offset++; } } // compute the clustering km = new Kmeans(pixels, numColors); float[] minv = new float[numColors]; float[] maxv = new float[numColors]; for (int i = 0; i < numColors; i++) { minv[i] = float.MaxValue; maxv[i] = float.MinValue; } // compute min and max v for each color cluster for (int y = 0; y < dds.Height; y++) { for (int x = 0; x < dds.Width; x++) { HSVColor hsv = HSVColor.FromRGB(dds.GetPixel(x, y)); int index = km.ClosestIndex(hsv); // record min and max v for each channel float v = hsv.V; if (v < minv[index]) { minv[index] = v; } if (v > maxv[index]) { maxv[index] = v; } } } for (int i = 0; i < numColors; i++) { if (minv[i] == float.MaxValue) { minv[i] = 0.0f; } if (maxv[i] == float.MinValue) { maxv[i] = 0.0f; } ColorInfo ci = new ColorInfo(i, minv[i], maxv[i], km.CenterColors[i]); colors.Add(ci); } colors.Sort(); // create the mapping from the kmeans returned colors to the sorted colors kmColorMap = new int[numColors]; for (int i = 0; i < numColors; i++) { kmColorMap[colors[i].KMIndex] = i; } }