/// <summary>Shrinks the RGBBox to be the tighest fitted box given the points inside. /// Also updates the volume of box /// </summary> /// <param name="box"></param> private void Shrink(ref RGBBox box) { int rmin = 255, rmax = 0; int gmin = 255, gmax = 0; int bmin = 255, bmax = 0; int color, red, green, blue; for (int i = box.lower; i <= box.upper; i++) { color = histPtr[i]; red = Red(color); green = Green(color); blue = Blue(color); //Update the min and max values for each color rmax = (red > rmax) ? red : rmax; rmin = (red < rmin) ? red : rmin; gmax = (green > gmax) ? green : gmax; gmin = (green < gmin) ? green : gmin; bmax = (blue > bmax) ? blue : bmax; bmin = (blue < bmin) ? blue : bmin; } box.rmax = rmax; box.rmin = rmin; box.gmax = gmax; box.gmin = gmin; box.bmax = bmax; box.bmin = bmin; box.volume = ((rmax - rmin) + 1) * ((gmax - gmin) + 1) * ((bmax - bmin) + 1); }
/// <summary>Returns the average color for all points in the box /// </summary> /// <param name="box"></param> /// <returns></returns> private void GetBoxAverageColor(RGBBox box, out int r, out int g, out int b) { int rtot = 0, gtot = 0, btot = 0; if (box == null) { MessageBoxResult result1 = MessageBox.Show("Ten obraz został już skwantowany. Nie możesz już powtórzyć procesu na tym pliku!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); if (result1 == MessageBoxResult.OK) { string path = AppDomain.CurrentDomain.BaseDirectory; path = path.Replace(@"\", "/"); Process.Start(path + "WhitePhoto.exe"); Process.GetCurrentProcess().Kill(); // goto Stop; } } //Sum the red, green, and blue components of all points in the box for (int i = box.lower; i <= box.upper; i++) { rtot += Red(histPtr[i]) * histogram[histPtr[i]]; gtot += Green(histPtr[i]) * histogram[histPtr[i]]; btot += Blue(histPtr[i]) * histogram[histPtr[i]]; } r = rtot / box.count; g = gtot / box.count; b = btot / box.count; if (grayscale) //Use grayscale if we're quantizing in grayscale { int color = (int)(0.212 * r) + (int)(0.7512 * g) + (int)(0.0722 * b); r = g = b = color; } }
/// <summary>Returns the median location of pixels in box, also sets count to be the # of pixels /// </summary> /// <param name="box"></param> /// <param name="count"></param> /// <returns></returns> private int FindMedianLocation(RGBBox box, ref int count) { int lenr, leng, lenb; LongAxis longdim; lenr = box.rmax - box.rmin; leng = box.gmax - box.gmin; lenb = box.bmax - box.bmin; if (lenr >= leng && lenr >= lenb) { longdim = LongAxis.Red; } else if (leng >= lenr && leng >= lenb) { longdim = LongAxis.Green; } else { longdim = LongAxis.Blue; } //Uses a delegate to correctly sort histPointer along the longest dimension histPtr.Sort(box.lower, box.upper - box.lower + 1, Comparer <int> .Create((int x, int y) => { int n1, n2; switch (longdim) { case LongAxis.Red: n1 = Red(x); n2 = Red(y); break; case LongAxis.Green: n1 = Green(x); n2 = Green(y); break; default: // Blue case n1 = Blue(x); n2 = Blue(y); break; } return(n1 - n2); })); count = 0; int i; for (i = box.lower; i < box.upper; i++) { if (count >= box.count / 2) { break; } count += histogram[histPtr[i]]; } return(i); }
/// <summary>Begins the median cut portion of the quantization /// </summary> private void BeginMedianCutQuantization() { RGBBox box, boxA = null, boxB = null; int color = 0; box = new RGBBox(0, 31, 0, 31, 0, 31); //Contruct the intial cube, which encloses all colors in the image for (int i = 0; i < HSIZE; i++) { if (histogram[i] != 0) { histPtr.Add(i); color++; box.count += histogram[i]; } } box.lower = 0; box.upper = color - 1; Shrink(ref box); list[boxcount] = box; boxcount++; int splitloc, median, level, count = 0; if (colorPalette == null) { while (boxcount < maxboxes) { level = 255; splitloc = -1; for (int k = 0; k < boxcount; k++) { if (list[k].lower == list[k].upper) { continue; } else if (list[k].level < level) { level = list[k].level; splitloc = k; } } if (splitloc == -1) { break; } box = list[splitloc]; median = FindMedianLocation(box, ref count); //Create box A which is the first half of the split of box boxA = new RGBBox(); boxA.count = count; boxA.lower = box.lower; boxA.upper = median - 1; boxA.level = box.level + 1; Shrink(ref boxA); list[splitloc] = boxA; //Replace old box with box A //Box b which will contain the upper points in box boxB = new RGBBox(); boxB.count = box.count - count; boxB.lower = median; boxB.upper = box.upper; boxB.level = box.level + 1; Shrink(ref boxB); list[boxcount++] = boxB; //Add b to the end of the list } } origHis = (int[])histogram.Clone(); }
/// <summary>Shrinks the RGBBox to be the tighest fitted box given the points inside. /// Also updates the volume of box /// </summary> /// <param name="box"></param> private void Shrink( ref RGBBox box ) { int rmin = 255, rmax = 0; int gmin = 255, gmax = 0; int bmin = 255, bmax = 0; int color, red, green, blue; for ( int i = box.lower; i <= box.upper; i++ ) { color = histPtr[i]; red = Red(color); green = Green(color); blue = Blue(color); //Update the min and max values for each color rmax = (red > rmax) ? red : rmax; rmin = (red < rmin) ? red : rmin; gmax = (green > gmax) ? green : gmax; gmin = (green < gmin) ? green : gmin; bmax = (blue > bmax) ? blue : bmax; bmin = (blue < bmin) ? blue : bmin; } box.rmax = rmax; box.rmin = rmin; box.gmax = gmax; box.gmin = gmin; box.bmax = bmax; box.bmin = bmin; box.volume = ((rmax - rmin) + 1) * ((gmax - gmin) + 1) * ((bmax - bmin) + 1); }
/// <summary>Returns the average color for all points in the box /// </summary> /// <param name="box"></param> /// <returns></returns> private void GetBoxAverageColor( RGBBox box, out int r, out int g, out int b ) { int rtot = 0, gtot = 0, btot = 0; //Sum the red, green, and blue components of all points in the box for ( int i = box.lower; i <= box.upper; i++ ) { rtot += Red(histPtr[i]) * histogram[histPtr[i]]; gtot += Green(histPtr[i]) * histogram[histPtr[i]]; btot += Blue(histPtr[i]) * histogram[histPtr[i]]; } r = rtot / box.count; g = gtot / box.count; b = btot / box.count; if ( grayscale ) //Use grayscale if we're quantizing in grayscale { int color = (int) (0.212 * r) + (int) (0.7512 * g) + (int) (0.0722 * b); r = g = b = color; } }
/// <summary>Returns the median location of pixels in box, also sets count to be the # of pixels /// </summary> /// <param name="box"></param> /// <param name="count"></param> /// <returns></returns> private int FindMedianLocation( RGBBox box, ref int count ) { int lenr, leng, lenb; LongAxis longdim; lenr = box.rmax - box.rmin; leng = box.gmax - box.gmin; lenb = box.bmax - box.bmin; if ( lenr >= leng && lenr >= lenb ) longdim = LongAxis.Red; else if ( leng >= lenr && leng >= lenb ) longdim = LongAxis.Green; else longdim = LongAxis.Blue; //Uses a delegate to correctly sort histPointer along the longest dimension histPtr.Sort(box.lower, box.upper - box.lower + 1, Comparer<int>.Create(( int x, int y ) => { int n1, n2; switch ( longdim ) { case LongAxis.Red: n1 = Red(x); n2 = Red(y); break; case LongAxis.Green: n1 = Green(x); n2 = Green(y); break; default: // Blue case n1 = Blue(x); n2 = Blue(y); break; } return n1 - n2; })); count = 0; int i; for ( i = box.lower; i < box.upper; i++ ) { if ( count >= box.count / 2 ) break; count += histogram[histPtr[i]]; } return i; }
/// <summary>Begins the median cut portion of the quantization /// </summary> private void BeginMedianCutQuantization() { RGBBox box, boxA = null, boxB = null; int color = 0; box = new RGBBox(0, 31, 0, 31, 0, 31); //Contruct the intial cube, which encloses all colors in the image for ( int i = 0; i < HSIZE; i++ ) { if ( histogram[i] != 0 ) { histPtr.Add(i); color++; box.count += histogram[i]; } } box.lower = 0; box.upper = color - 1; Shrink(ref box); list[boxcount] = box; boxcount++; int splitloc, median, level, count = 0; if ( colorPalette == null ) { while ( boxcount < maxboxes ) { level = 255; splitloc = -1; for ( int k = 0; k < boxcount; k++ ) { if ( list[k].lower == list[k].upper ) continue; else if ( list[k].level < level ) { level = list[k].level; splitloc = k; } } if ( splitloc == -1 ) break; box = list[splitloc]; median = FindMedianLocation(box, ref count); //Create box A which is the first half of the split of box boxA = new RGBBox(); boxA.count = count; boxA.lower = box.lower; boxA.upper = median - 1; boxA.level = box.level + 1; Shrink(ref boxA); list[splitloc] = boxA; //Replace old box with box A //Box b which will contain the upper points in box boxB = new RGBBox(); boxB.count = box.count - count; boxB.lower = median; boxB.upper = box.upper; boxB.level = box.level + 1; Shrink(ref boxB); list[boxcount++] = boxB; //Add b to the end of the list } } origHis = (int[]) histogram.Clone(); }