public void ReadScanline(byte[] scanline, Color2[] pixels, PngHeader header) { int offset; byte[] newScanline = GrayscaleReader.ToArrayByBitsLength(scanline,header.BitDepth); if (useAlpha){ for (int x = 0; x < newScanline.Length; x += 4){ offset = row*header.Width + (x >> 2); byte r = newScanline[x]; byte g = newScanline[x + 1]; byte b = newScanline[x + 2]; byte a = newScanline[x + 3]; Color2 color = Color2.FromArgb(a,r, g, b); pixels[offset] = color; } } else{ for (int x = 0; x < newScanline.Length/3; x++){ offset = (row*header.Width) + x; int pixelOffset = x*3; byte r = newScanline[pixelOffset]; byte g = newScanline[pixelOffset + 1]; byte b = newScanline[pixelOffset + 2]; Color2 color = Color2.FromArgb(r, g, b); pixels[offset] = color; } } row++; }
/// <summary> /// Reads the specified scanline. /// </summary> /// <param name="scanline">The scanline.</param> /// <param name="pixels">The pixels, where the colors should be stored in RGBA format.</param> /// <param name="header">The header, which contains information about the png file, like /// the width of the image and the height.</param> public void ReadScanline(byte[] scanline, byte[] pixels, PngHeader header) { int offset = 0; byte[] newScanline = PngColorReader.ToArrayByBitsLength(scanline, header.BitDepth); if (_useAlpha) { for (int x = 0; x < header.Width / 2; x++) { offset = (_row * header.Width + x) * 4; pixels[offset + 0] = newScanline[x * 2]; pixels[offset + 1] = newScanline[x * 2]; pixels[offset + 2] = newScanline[x * 2]; pixels[offset + 3] = newScanline[x * 2 + 1]; } } else { for (int x = 0; x < header.Width; x++) { offset = (_row * header.Width + x) * 4; pixels[offset + 0] = newScanline[x]; pixels[offset + 1] = newScanline[x]; pixels[offset + 2] = newScanline[x]; pixels[offset + 3] = (byte)255; } } _row++; }
public void ReadScanline(byte[] scanline, Color2[] pixels, PngHeader header) { byte[] newScanline = GrayscaleReader.ToArrayByBitsLength(scanline,header.BitDepth); int offset, index; if (paletteAlpha != null && paletteAlpha.Length > 0){ for (int i = 0; i < header.Width; i++){ index = newScanline[i]; offset = (row*header.Width) + i; int pixelOffset = index*3; byte r = palette[pixelOffset]; byte g = palette[pixelOffset + 1]; byte b = palette[pixelOffset + 2]; byte a = paletteAlpha.Length > index ? paletteAlpha[index] : (byte) 255; Color2 color = Color2.FromArgb(a,r, g, b); pixels[offset] = color; } } else{ for (int i = 0; i < header.Width; i++){ index = newScanline[i]; offset = (row*header.Width) + i; int pixelOffset = index*3; byte r = palette[pixelOffset]; byte g = palette[pixelOffset + 1]; byte b = palette[pixelOffset + 2]; Color2 color = Color2.FromArgb(r, g, b); pixels[offset] = color; } } row++; }
/// <inheritdoc/> public void ReadScanline(byte[] scanline, float[] pixels, PngHeader header) { byte[] newScanline = scanline.ToArrayByBitsLength(header.BitDepth); int offset, index; if (this.paletteAlpha != null && this.paletteAlpha.Length > 0) { // If the alpha palette is not null and does one or // more entries, this means, that the image contains and alpha // channel and we should try to read it. for (int i = 0; i < header.Width; i++) { index = newScanline[i]; offset = ((this.row * header.Width) + i) * 4; int pixelOffset = index * 3; // BUGFIX changed newScanline[] to this.palette[] , 99% sure it was a typo and not intent float r = this.palette[pixelOffset] / 255f; float g = this.palette[pixelOffset + 1] / 255f; float b = this.palette[pixelOffset + 2] / 255f; float a = this.paletteAlpha.Length > index ? this.paletteAlpha[index] / 255f : 1; Color color = new Color(r, g, b, a); if (color.A < 1) { // We want to convert to premultiplied alpha here. color = Color.FromNonPremultiplied(color); } pixels[offset] = color.R; pixels[offset + 1] = color.G; pixels[offset + 2] = color.B; pixels[offset + 3] = color.A; } } else { for (int i = 0; i < header.Width; i++) { index = newScanline[i]; offset = ((this.row * header.Width) + i) * 4; int pixelOffset = index * 3; pixels[offset] = this.palette[pixelOffset] / 255f; pixels[offset + 1] = this.palette[pixelOffset + 1] / 255f; pixels[offset + 2] = this.palette[pixelOffset + 2] / 255f; pixels[offset + 3] = 1; } } this.row++; }
/// <summary> /// Write and PNG file out to a file stream. Currently compression is not supported. /// </summary> /// <param name="image">The WriteableBitmap to work on.</param> /// <param name="stream">The destination file stream.</param> /// <param name="compression">Level of compression to use (-1=auto, 0=none, 1-100 is percentage).</param> public static void WritePNG(WriteableBitmap image, System.IO.Stream stream, int compression) { var writer = new PNGWriter() { _stream = stream, _image = image }; // Write the png header. stream.Write( new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, 0, 8); // Set the PNG header values for this image. PngHeader header = new PngHeader(); header.Width = image.PixelWidth; header.Height = image.PixelHeight; header.ColorType = 6; header.BitDepth = 8; header.FilterMethod = 0; header.CompressionMethod = 0; header.InterlaceMethod = 0; // Write out the header. writer.WriteHeaderChunk(header); // Write out the rest of the mandatory fields to the PNG. writer.WritePhysicsChunk(); writer.WriteGammaChunk(); // Currently only uncompressed PNG's are supported, so this if statement really doesn't do anything ;). if (compression == -1) { // Autodetect compression setting writer.WriteDataChunksUncompressed(); } else if (compression == 0) { // Write PNG without any compression writer.WriteDataChunksUncompressed(); } else { // Write the PNG with a desired compression level writer.WriteDataChunks(compression); } // Write out the end of the PNG. writer.WriteEndChunk(); // Flush the stream to make sure it's all written. stream.Flush(); }
/// <summary> /// Reads the specified scanline. /// </summary> /// <param name="scanline">The scanline.</param> /// <param name="pixels">The pixels, where the colors should be stored in RGBA format.</param> /// <param name="header">The header, which contains information about the png file, like /// the width of the image and the height.</param> public void ReadScanline(byte[] scanline, byte[] pixels, PngHeader header) { int offset = 0; byte[] newScanline = PngColorReader.ToArrayByBitsLength(scanline, header.BitDepth); if (_useAlpha) { for (int x = 0; x < newScanline.Length; x += 4) { offset = (_row * header.Width + (x >> 2)) * 4; pixels[offset + 0] = newScanline[x + 2]; pixels[offset + 1] = newScanline[x + 1]; pixels[offset + 2] = newScanline[x + 0]; pixels[offset + 3] = newScanline[x + 3]; } } else { if (header.BitDepth == 8) { for (int x = 0; x < newScanline.Length / 3; x++) { offset = (_row * header.Width + x) * 4; pixels[offset + 0] = newScanline[x * 3 + 2]; pixels[offset + 1] = newScanline[x * 3 + 1]; pixels[offset + 2] = newScanline[x * 3 + 0]; pixels[offset + 3] = (byte)255; } } else { for (int x = 0; x < newScanline.Length / 6; x++) { offset = (_row * header.Width + x) * 4; pixels[offset + 0] = newScanline[(x * 6 + 4)]; pixels[offset + 1] = newScanline[(x * 6 + 2)]; pixels[offset + 2] = newScanline[(x * 6 + 0)]; pixels[offset + 3] = (byte)255; } } } _row++; }
/// <inheritdoc/> public void ReadScanline(byte[] scanline, float[] pixels, PngHeader header) { int offset; byte[] newScanline = scanline.ToArrayByBitsLength(header.BitDepth); // We divide by 255 as we will store the colors in our floating point format. // Stored in r-> g-> b-> a order. if (this.useAlpha) { for (int x = 0; x < header.Width / 2; x++) { offset = ((this.row * header.Width) + x) * 4; // We want to convert to premultiplied alpha here. float r = newScanline[x * 2] / 255f; float g = newScanline[x * 2] / 255f; float b = newScanline[x * 2] / 255f; float a = newScanline[(x * 2) + 1] / 255f; Color premultiplied = Color.FromNonPremultiplied(new Color(r, g, b, a)); pixels[offset] = premultiplied.R; pixels[offset + 1] = premultiplied.G; pixels[offset + 2] = premultiplied.B; pixels[offset + 3] = premultiplied.A; } } else { for (int x = 0; x < header.Width; x++) { offset = ((this.row * header.Width) + x) * 4; pixels[offset] = newScanline[x] / 255f; pixels[offset + 1] = newScanline[x] / 255f; pixels[offset + 2] = newScanline[x] / 255f; pixels[offset + 3] = 1; } } this.row++; }
/// <inheritdoc/> public void ReadScanline(byte[] scanline, float[] pixels, PngHeader header) { int offset; byte[] newScanline = scanline.ToArrayByBitsLength(header.BitDepth); if (this.useAlpha) { for (int x = 0; x < newScanline.Length; x += 4) { offset = ((this.row * header.Width) + (x >> 2)) * 4; // We want to convert to premultiplied alpha here. float r = newScanline[x] / 255f; float g = newScanline[x + 1] / 255f; float b = newScanline[x + 2] / 255f; float a = newScanline[x + 3] / 255f; Color premultiplied = Color.FromNonPremultiplied(new Color(r, g, b, a)); pixels[offset] = premultiplied.R; pixels[offset + 1] = premultiplied.G; pixels[offset + 2] = premultiplied.B; pixels[offset + 3] = premultiplied.A; } } else { for (int x = 0; x < newScanline.Length / 3; x++) { offset = ((this.row * header.Width) + x) * 4; int pixelOffset = x * 3; pixels[offset] = newScanline[pixelOffset] / 255f; pixels[offset + 1] = newScanline[pixelOffset + 1] / 255f; pixels[offset + 2] = newScanline[pixelOffset + 2] / 255f; pixels[offset + 3] = 1; } } this.row++; }
/// <summary> /// Reads the specified scanline. /// </summary> /// <param name="scanline">The scanline.</param> /// <param name="pixels">The pixels, where the colors should be stored in RGBA format.</param> /// <param name="header">The header, which contains information about the png file, like /// the width of the image and the height.</param> public void ReadScanline(byte[] scanline, byte[] pixels, PngHeader header) { byte[] newScanline = PngColorReader.ToArrayByBitsLength(scanline, header.BitDepth); int offset = 0, index = 0; if (_paletteAlpha != null && _paletteAlpha.Length > 0) { // If the alpha palette is not null and does one or // more entries, this means, that the image contains and alpha // channel and we should try to read it. for (int i = 0; i < header.Width; i++) { index = newScanline[i]; offset = (_row * header.Width + i) * 4; pixels[offset + 0] = _palette[index * 3 + 2]; pixels[offset + 1] = _palette[index * 3 + 1]; pixels[offset + 2] = _palette[index * 3 + 0]; pixels[offset + 3] = _paletteAlpha.Length > index ? _paletteAlpha[index] : (byte)255; } } else { for (int i = 0; i < header.Width; i++) { index = newScanline[i]; offset = (_row * header.Width + i) * 4; pixels[offset + 0] = _palette[index * 3 + 2]; pixels[offset + 1] = _palette[index * 3 + 1]; pixels[offset + 2] = _palette[index * 3 + 0]; pixels[offset + 3] = (byte)255; } } _row++; }
private static void WriteHeaderChunk(PngHeader header) { byte[] chunkData = new byte[13]; WriteInteger(chunkData, 0, header.Width); WriteInteger(chunkData, 4, header.Height); chunkData[8] = header.BitDepth; chunkData[9] = header.ColorType; chunkData[10] = header.CompressionMethod; chunkData[11] = header.FilterMethod; chunkData[12] = header.InterlaceMethod; WriteChunk(PngChunkTypes.Header, chunkData); }
public override void Save(Gdk.Pixbuf pixbuf, System.IO.Stream stream) { byte [] buffer = PixbufUtils.Save (pixbuf, "png", null, null); using (MemoryStream mem = new MemoryStream (buffer)) { PngHeader converted = new PngHeader (mem); /* FIXME we need to update the XMP metadata here */ foreach (Chunk c in Chunks) { if (c is TextChunk) { converted.Insert (c); } } converted.Save (stream); } }
public abstract void ReadScanline(byte[] scanline, byte[] pixels, PngHeader header);