public static Image2 Quantize(this Image2 source, IQuantizer quantizer, int maxColors) { QuantizedImage quantizedImage = quantizer.Quantize(source, maxColors); source.SetPixels(source.Width, source.Height, quantizedImage.ToImage().Pixels); return(source); }
public Image2 ToImage() { Image2 image = new Image2(); int pixelCount = Pixels.Length; int palletCount = Palette.Length - 1; Color2[] pixels = new Color2[pixelCount]; Parallel.For(0, pixelCount, Bootstrapper.instance.ParallelOptions, i =>{ Color2 color = Palette[Math.Min(palletCount, Pixels[i])]; pixels[i] = color; }); image.SetPixels(Width, Height, pixels); return image; }
public Image2 ToImage() { Image2 image = new Image2(); int pixelCount = Pixels.Length; int palletCount = Palette.Length - 1; Color2[] pixels = new Color2[pixelCount]; Parallel.For(0, pixelCount, Bootstrapper.instance.ParallelOptions, i => { Color2 color = Palette[Math.Min(palletCount, Pixels[i])]; pixels[i] = color; }); image.SetPixels(Width, Height, pixels); return(image); }
public void Decode(Image2 image, Stream stream) { currentStream = stream; try{ ReadFileHeader(); ReadInfoHeader(); bool inverted = false; if (infoHeader.Height < 0) { inverted = true; infoHeader.Height = -infoHeader.Height; } int colorMapSize = -1; if (infoHeader.ClrUsed == 0) { if (infoHeader.BitsPerPixel == 1 || infoHeader.BitsPerPixel == 4 || infoHeader.BitsPerPixel == 8) { colorMapSize = (int)Math.Pow(2, infoHeader.BitsPerPixel) * 4; } } else { colorMapSize = infoHeader.ClrUsed * 4; } byte[] palette = null; if (colorMapSize > 0) { // 255 * 4 if (colorMapSize > 1020) { throw new Exception($"Invalid bmp colormap size '{colorMapSize}'"); } palette = new byte[colorMapSize]; currentStream.Read(palette, 0, colorMapSize); } if (infoHeader.Width > image.MaxWidth || infoHeader.Height > image.MaxHeight) { throw new ArgumentOutOfRangeException($"The input bitmap '{infoHeader.Width}x{infoHeader.Height}' is " + $"bigger then the max allowed size '{image.MaxWidth}x{image.MaxHeight}'"); } Color2[] imageData = new Color2[infoHeader.Width * infoHeader.Height]; switch (infoHeader.Compression) { case BmpCompression.Rgb: if (infoHeader.HeaderSize != 40) { throw new Exception($"Header Size value '{infoHeader.HeaderSize}' is not valid."); } if (infoHeader.BitsPerPixel == 32) { ReadRgb32(imageData, infoHeader.Width, infoHeader.Height, inverted); } else if (infoHeader.BitsPerPixel == 24) { ReadRgb24(imageData, infoHeader.Width, infoHeader.Height, inverted); } else if (infoHeader.BitsPerPixel == 16) { ReadRgb16(imageData, infoHeader.Width, infoHeader.Height, inverted); } else if (infoHeader.BitsPerPixel <= 8) { ReadRgbPalette(imageData, palette, infoHeader.Width, infoHeader.Height, infoHeader.BitsPerPixel, inverted); } break; default: throw new NotSupportedException("Does not support this kind of bitmap files."); } image.SetPixels(infoHeader.Width, infoHeader.Height, imageData); } catch (IndexOutOfRangeException e) { throw new Exception("Bitmap does not have a valid format.", e); } }
public void Decode(Image2 image, Stream stream) { Image2 currentImage = image; currentStream = stream; currentStream.Seek(8, SeekOrigin.Current); bool isEndChunkReached = false; byte[] palette = null; byte[] paletteAlpha = null; using (MemoryStream dataStream = new MemoryStream()){ PngChunk currentChunk; while ((currentChunk = ReadChunk()) != null) { if (isEndChunkReached) { throw new Exception("Image does not end with end chunk."); } if (currentChunk.Type == PngChunkTypes.Header) { ReadHeaderChunk(currentChunk.Data); ValidateHeader(); } else if (currentChunk.Type == PngChunkTypes.Physical) { ReadPhysicalChunk(currentImage, currentChunk.Data); } else if (currentChunk.Type == PngChunkTypes.Data) { dataStream.Write(currentChunk.Data, 0, currentChunk.Data.Length); } else if (currentChunk.Type == PngChunkTypes.Palette) { palette = currentChunk.Data; } else if (currentChunk.Type == PngChunkTypes.PaletteAlpha) { paletteAlpha = currentChunk.Data; } else if (currentChunk.Type == PngChunkTypes.Text) { ReadTextChunk(currentImage, currentChunk.Data); } else if (currentChunk.Type == PngChunkTypes.End) { isEndChunkReached = true; } } if (header.Width > image.MaxWidth || header.Height > image.MaxHeight) { throw new ArgumentOutOfRangeException($"The input png '{header.Width}x{header.Height}' is bigger than the " + $"max allowed size '{image.MaxWidth}x{image.MaxHeight}'"); } Color2[] pixels = new Color2[header.Width * header.Height]; PngColorTypeInformation colorTypeInformation = colorTypes[header.ColorType]; if (colorTypeInformation != null) { IColorReader colorReader = colorTypeInformation.CreateColorReader(palette, paletteAlpha); ReadScanlines(dataStream, pixels, colorReader, colorTypeInformation); } image.SetPixels(header.Width, header.Height, pixels); } }