public static Palette Generate(PixelBuffer pixelBuffer, Rectangle region) { Tizen.Log.Info("Palette", "pixelBuffer generate start with region: " + region + "\n"); if (pixelBuffer == null) { throw new ArgumentNullException(nameof(pixelBuffer), "pixelBuffer should not be null."); } // First we'll scale down the bitmap so it's shortest dimension is 100px // NOTE: scaledBitmap can gets bitmap origin value and new bitmap instance as well // When ScaleBitmap created newly it will be dispose below. // otherwise it should not disposed because of this instance from user side. bool resized = ScaleBitmapDown(pixelBuffer); // Region set if (resized && region != null) { double scale = pixelBuffer.GetWidth() / (double)pixelBuffer.GetHeight(); region.X = (int)Math.Floor(region.X * scale); region.Y = (int)Math.Floor(region.Y * scale); region.Width = Math.Min((int)Math.Ceiling(region.Width * scale), (int)pixelBuffer.GetWidth()); region.Height = Math.Min((int)Math.Ceiling(region.Height * scale), (int)pixelBuffer.GetHeight()); } // Now generate a Quantizer from the Bitmap // FIXME: defaultCalculateNumberColors should be changeable? ColorCutQuantizer quantizer = ColorCutQuantizer.FromBitmap(pixelBuffer, region, defaultCalculateNumberColors); // Now return a ColorExtractor instance return(new Palette(quantizer.GetQuantizedColors())); }
/// <summary> /// Scale the bitmap down so that it's smallest dimension is /// calculateBitmapMinDimensionpx. If bitmap is smaller than this, than it /// is returned. /// </summary> private static bool ScaleBitmapDown(PixelBuffer pixelBuffer) { int minDimension = Math.Min((int)pixelBuffer.GetWidth(), (int)pixelBuffer.GetHeight()); if (minDimension <= calculateBitmapMinDimension) { // If the bitmap is small enough already, just return it return(false); } float scaleRatio = calculateBitmapMinDimension / (float)minDimension; int width = (int)Math.Round((int)pixelBuffer.GetWidth() * scaleRatio); int height = (int)Math.Round((int)pixelBuffer.GetHeight() * scaleRatio); Tizen.Log.Info("Palette", "pixelBuffer resize to " + width + " " + height + "\n"); pixelBuffer.Resize((ushort)width, (ushort)height); return(true); }
/// <summary> /// Factory-method to generate a ColorCutQuantizer from a PixelBuffer object. /// </summary> public static ColorCutQuantizer FromBitmap(PixelBuffer pixelBuffer, Rectangle region, int maxColors) { int width; int height; int[] pixels; int i, j, index = 0; if (region == null) { width = (int)pixelBuffer.GetWidth(); height = (int)pixelBuffer.GetHeight(); i = 0; j = 0; } else { width = region.Width; height = region.Height; i = region.X; j = region.Y; } Tizen.Log.Info("Palette", "Get pixels rawdata from (" + i + " " + j + " " + width + " " + height + ")" + "\n"); pixels = new int[width * height]; PixelFormat format = pixelBuffer.GetPixelFormat(); int pixelLength = (int)ColorUtils.GetBytesPerPixel(format); IntPtr bufferIntPtr = pixelBuffer.GetBuffer(); unsafe { byte *rawdata = (byte *)bufferIntPtr.ToPointer(); int totalLength = width * height * pixelLength; for (i = 0; i < totalLength; i += pixelLength) { //RGB888 if (pixelLength == 3) { pixels[index++] = (255 & 0xff) << 24 | (rawdata[i] & 0xff) << 16 | (rawdata[i + 1] & 0xff) << 8 | (rawdata[i + 2] & 0xff); } //RGBA8888 else { pixels[index++] = (rawdata[i + 3] & 0xff) << 24 | (rawdata[i] & 0xff) << 16 | (rawdata[i + 1] & 0xff) << 8 | (rawdata[i + 2] & 0xff); } } } return(new ColorCutQuantizer(new ColorHistogram(pixels), maxColors)); }