public static void tile(String orig, String dest, int factor) { if (orig.Equals(dest)) { throw new PngjException("input and output file cannot coincide"); } if (factor < 2 || factor > 100) { throw new PngjException("bad factor "); } PngReader pngr = FileHelper.CreatePngReader(orig); var x = pngr.ImgInfo; PngWriter pngw = FileHelper.CreatePngWriter(dest, pngr.ImgInfo, true); pngr.SetUnpackedMode(true); // we dont want to do the unpacking ourselves, we want a sample per array element pngw.SetUseUnPackedMode(true); // not really necesary here, as we pass the ImageLine, but anyway... pngw.CopyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE); for (int row = 0; row < pngr.ImgInfo.Rows; row++) { ImageLine l1 = pngr.ReadRowInt(row); mirrorLineInt(pngr.ImgInfo, l1.Scanline); pngw.WriteRow(l1, row); } pngw.CopyChunksLast(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE); pngw.End(); }
private static void additionalTestInterlaced(string orig, string origni) { // tests also read/write in packed format PngReader pngr = FileHelper.CreatePngReader(orig); string copy = TestsHelper.addSuffixToName(orig, "_icopy"); pngr.SetUnpackedMode(false); PngWriter pngw = FileHelper.CreatePngWriter(copy, pngr.ImgInfo, true); pngw.CopyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL); pngw.SetUseUnPackedMode(false); Random random = new Random(); bool useByte = random.NextDouble() > 0.5 && pngr.ImgInfo.BitDepth < 16; for (int row = 0; row < pngr.ImgInfo.Rows; row++) { if (useByte) { ImageLine line = pngr.ReadRowByte(row); pngw.WriteRow(line, row); } else { ImageLine line = pngr.ReadRowInt(row); pngw.WriteRow(line, row); } } pngr.End(); pngw.End(); TestsHelper.testEqual(copy, origni); System.IO.File.Delete(copy); }
public static void addMetadata(String origFilename, Dictionary <string, string> data) { String destFilename = "tmp.png"; PngReader pngr = FileHelper.CreatePngReader(origFilename); // or you can use the constructor PngWriter pngw = FileHelper.CreatePngWriter(destFilename, pngr.ImgInfo, true); // idem //Console.WriteLine(pngr.ToString()); // just information int chunkBehav = ChunkCopyBehaviour.COPY_ALL_SAFE; // tell to copy all 'safe' chunks pngw.CopyChunksFirst(pngr, chunkBehav); // copy some metadata from reader foreach (string key in data.Keys) { PngChunk chunk = pngw.GetMetadata().SetText(key, data[key]); chunk.Priority = true; } int channels = pngr.ImgInfo.Channels; if (channels < 3) { throw new Exception("This example works only with RGB/RGBA images"); } for (int row = 0; row < pngr.ImgInfo.Rows; row++) { ImageLine l1 = pngr.ReadRowInt(row); // format: RGBRGB... or RGBARGBA... pngw.WriteRow(l1, row); } pngw.CopyChunksLast(pngr, chunkBehav); // metadata after the image pixels? can happen pngw.End(); // dont forget this pngr.End(); File.Delete(origFilename); File.Move(destFilename, origFilename); }
public void LoadFromP8PNG(Stream stream) { PngReader reader = new PngReader(stream); if (!validatePNG(reader.ImgInfo)) { throw new BadImageFormatException("Bad Cart"); } int offset = 0; for (int row = 0; row < reader.ImgInfo.Rows && offset < CART_SIZE; row++) { ImageLine line = reader.ReadRowInt(row); for (int col = 0; col < line.ImgInfo.Cols && offset < CART_SIZE; col++) { rom[offset] = decodeBytes(line.Scanline, col * 4); offset += 1; } } Version = rom[0x8000]; Build = (rom[0x8001] << 24) + (rom[0x8002] << 16) + (rom[0x8003] << 8) + rom[0x8004]; /* * Debug.Log(rom[0]); * Debug.Log(rom[1]); * Debug.Log(rom[2]); * Debug.Log(rom[3]); */ reader.End(); }
public static void doit(String orig) { string copy = TestsHelper.addSuffixToName(orig, "_tc"); PngReader pngr = FileHelper.CreatePngReader(orig); if (!pngr.ImgInfo.Indexed) { throw new Exception("Not indexed image"); } PngChunkPLTE plte = pngr.GetMetadata().GetPLTE(); PngChunkTRNS trns = pngr.GetMetadata().GetTRNS(); // transparency metadata, can be null bool alpha = trns != null; ImageInfo im2 = new ImageInfo(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 8, alpha); PngWriter pngw = FileHelper.CreatePngWriter(copy, im2, true); pngw.CopyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE); int[] buf = null; for (int row = 0; row < pngr.ImgInfo.Rows; row++) { ImageLine line = pngr.ReadRowInt(row); buf = ImageLineHelper.Palette2rgb(line, plte, trns, buf); pngw.WriteRowInt(buf, row); } pngw.CopyChunksLast(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE); pngr.End(); pngw.End(); Console.WriteLine("True color: " + copy); }
static void testmirror(string orig, string origni, string truecolor) { string mirror = TestsHelper.addSuffixToName(orig, "_mirror"); string recov = TestsHelper.addSuffixToName(orig, "_recov"); long crc0 = 0; bool interlaced; bool palete; { PngReader pngr = FileHelper.CreatePngReader(orig); palete = pngr.ImgInfo.Indexed; PngHelperInternal.InitCrcForTests(pngr); pngr.SetUnpackedMode(true); interlaced = pngr.IsInterlaced(); PngWriter pngw = FileHelper.CreatePngWriter(mirror, pngr.ImgInfo, true); pngw.SetFilterType(FilterType.FILTER_CYCLIC); // just to test all filters pngw.CopyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL); pngw.SetUseUnPackedMode(true); for (int row = 0; row < pngr.ImgInfo.Rows; row++) { ImageLine line = pngr.ReadRowInt(row); mirrorLine(line); pngw.WriteRow(line, row); } pngr.End(); crc0 = PngHelperInternal.GetCrctestVal(pngr); pngw.CopyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL); pngw.End(); } // mirror again, now with BYTE (if depth<16) and loading all rows { PngReader pngr2 = FileHelper.CreatePngReader(mirror); pngr2.SetUnpackedMode(true); PngWriter pngw = FileHelper.CreatePngWriter(recov, pngr2.ImgInfo, true); pngw.SetFilterType(FilterType.FILTER_AGGRESSIVE); pngw.CopyChunksFirst(pngr2, ChunkCopyBehaviour.COPY_ALL); pngw.SetUseUnPackedMode(true); ImageLines lines = pngr2.ImgInfo.BitDepth < 16 ? pngr2.ReadRowsByte() : pngr2 .ReadRowsInt(); for (int row = 0; row < pngr2.ImgInfo.Rows; row++) { ImageLine line = lines.GetImageLineAtMatrixRow(row); mirrorLine(line); pngw.WriteRow(line, row); } pngr2.End(); pngw.End(); } // now check if (orig[11] != 'i') { TestsHelper.testCrcEquals(recov, crc0); } //if (interlaced) // additionalTestInterlaced(orig, origni); //if (palete && System.IO.File.Exists(truecolor)) // additionalTestPalette(orig, truecolor); }
//--------------------------------------------------------------------- public void foreachPixel(onPixel fun) { for (int y = 0; y < height; ++y) { // ImageLine的Scanline出来的行数据,表示RGBA ImageLine pngLine = mPngReader.ReadRowInt(y); int[] pngLineArray = pngLine.Scanline; for (int x = 0; x < width; ++x) { fun(_isBlackColor(pngLineArray, x), x, y); } } }
public static Texture2D FromPng(Stream stream, Texture2D texture = null) { var pngr = new PngReader(stream); var ms = new MemoryStream(); int channels = pngr.ImgInfo.Channels; int w = pngr.ImgInfo.Cols; int h = pngr.ImgInfo.Rows; var bytes = new byte[w * h * channels]; int count = 0; for (int row = 0; row < pngr.ImgInfo.Rows; row++) { ImageLine l1 = pngr.ReadRowInt(row); // Format: RGBRGB... or RGBARGBA... for (int j = 0; j < pngr.ImgInfo.Cols; j++) { byte R = (byte)l1.Scanline[j * channels]; byte G = (byte)l1.Scanline[j * channels + 1]; byte B = (byte)l1.Scanline[j * channels + 2]; byte A = (byte)l1.Scanline[j * channels + 3]; bytes[count++] = B; bytes[count++] = G; bytes[count++] = R; bytes[count++] = A; } } ms.Close(); pngr.End(); if (texture == null) { texture = new Texture2D(GameClass.Graphics, w, h); } texture.SetData(bytes); return(texture); }
private static void additionalTestPalette(string orig, string truecolor) { // covnert to true color 8 bits and check equality PngReader pngr = FileHelper.CreatePngReader(orig); PngChunkPLTE plte = pngr.GetMetadata().GetPLTE(); PngChunkTRNS trns = pngr.GetMetadata().GetTRNS(); string copy = TestsHelper.addSuffixToName(orig, "_tccopy"); bool alpha = trns != null; ImageInfo im2 = new ImageInfo(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 8, alpha); PngWriter pngw = FileHelper.CreatePngWriter(copy, im2, true); pngw.CopyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE); int[] buf = null; for (int row = 0; row < pngr.ImgInfo.Rows; row++) { ImageLine line = pngr.ReadRowInt(row); buf = ImageLineHelper.Palette2rgb(line, plte, trns, buf); pngw.WriteRowInt(buf, row); } pngr.End(); pngw.End(); TestsHelper.testEqual(copy, truecolor); System.IO.File.Delete(copy); }
private unsafe void ReadPng(Stream bitmapStream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption) { var pngr = new PngReader(bitmapStream); if (pngr.ImgInfo.Channels > 4 || pngr.ImgInfo.Channels < 3 || pngr.ImgInfo.BitDepth != 8) { throw new NotSupportedException("PNG must be RGB8/RGBA8"); } var channels = pngr.ImgInfo.Channels; var data = new byte[pngr.ImgInfo.Cols * pngr.ImgInfo.Rows * channels]; var alpha = (channels == 4); if (alpha) { fixed(byte *dataStart = &data[0]) { var d = dataStart; for (var i = 0; i < pngr.ImgInfo.Rows; i++) { var line = pngr.ReadRowByte(i); for (var j = 0; j < pngr.ImgInfo.Cols; j++) { var j2 = j * channels; * d++ = line.ScanlineB[j2 + 2]; * d++ = line.ScanlineB[j2 + 1]; * d++ = line.ScanlineB[j2]; * d++ = line.ScanlineB[j2 + 3]; } } Source = BitmapSource.Create(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 100, 100, PixelFormats.Bgra32, null, (IntPtr)dataStart, pngr.ImgInfo.Cols * pngr.ImgInfo.Rows * channels, pngr.ImgInfo.Cols * channels); } //for (int i = 0; i < pngr.ImgInfo.Rows; i++) //{ // var i1 = i * pngr.ImgInfo.Cols * channels; // ImageLine line = pngr.ReadRowInt(i); // for (int j = 0; j < pngr.ImgInfo.Cols; j++) // { // var j1 = i1 + j * channels; // var j2 = j * channels; // data[j1+2] = (byte)line.Scanline[j2++]; // data[j1 + 1] = (byte)line.Scanline[j2++]; // data[j1] = (byte)line.Scanline[j2++]; // data[j1 + 3] = (byte)line.Scanline[j2]; // } //} //Source = BitmapSource.Create(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 100, 100, PixelFormats.Bgra32, null, data, pngr.ImgInfo.Cols * channels); //Source = BitmapSource.Create(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 100, 100, PixelFormats.Bgra32, null, data, stride); } else { fixed(byte *dataStart = &data[0]) { var d = dataStart; for (var i = 0; i < pngr.ImgInfo.Rows; i++) { var line = pngr.ReadRowInt(i); for (var j = 0; j < pngr.ImgInfo.Cols; j++) { var j2 = j * channels; * d++ = (byte)line.Scanline[j2 + 2]; * d++ = (byte)line.Scanline[j2 + 1]; * d++ = (byte)line.Scanline[j2]; } } Source = BitmapSource.Create(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 100, 100, PixelFormats.Bgr24, null, data, pngr.ImgInfo.Cols * channels); } } pngr.End(); //double dpi = 96; //int width = 128; //int height = 128; //byte[] pixelData = new byte[width * height]; //for (int y = 0; y < height; ++y) //{ // int yIndex = y * width; // for (int x = 0; x < width; ++x) // { // pixelData[x + yIndex] = (byte)(x + y); // } //} //Source = BitmapSource.Create(width, height, dpi, dpi, // PixelFormats.Gray8, null, pixelData, width); //Source = source; Source.Freeze(); }
/// <summary> Create Color[] from PNG file </summary> public static ReadColorsResult ReadColors ( string filePath ) { ReadColorsResult results = new ReadColorsResult { pixels = null, width = -1, height = -1, textureFormatInfered = 0 }; PngReader reader = null; try { reader = FileHelper.CreatePngReader(filePath); var info = reader.ImgInfo; results.height = info.Rows; results.width = info.Cols; results.pixels = new Color[results.width * results.height]; int channels = info.Channels; int bitDepth = info.BitDepth; if (info.Indexed) { throw new System.NotImplementedException("indexed png not implemented"); } //select appropriate texture format: results.textureFormatInfered = GetTextureFormat(bitDepth, channels); //create pixel array: for (int row = 0; row < results.height; row++) { ImageLine imageLine = reader.ReadRowInt(row); var scanline = imageLine.Scanline; if (imageLine.SampleType == ImageLine.ESampleType.INT) { for (int col = 0; col < results.width; col++) { var color = new Color(); for (int ch = 0; ch < channels; ch++) { int raw = scanline[col * channels + ch]; float rawMax = GetBitDepthMaxValue(bitDepth); float value = (float)raw / rawMax; // if (ch == 0) { color.r = value; } else if (ch == 1) { color.g = value; } else if (ch == 2) { color.b = value; } else if (ch == 3) { color.a = value; } else { throw new System.Exception($"channel { ch } not implemented"); } } results.pixels[IndexPngToTexture(row, col, results.height, results.width)] = color; } } else { throw new System.Exception($"imageLine.SampleType { imageLine.SampleType } not implemented"); } } } catch (System.Exception ex) { Debug.LogException(ex); if (results.pixels == null) { results.width = 2; results.height = 2; results.pixels = new Color[results.width * results.height]; } if (results.textureFormatInfered == 0) { results.textureFormatInfered = TextureFormat.RGBA32; } } finally { if (reader != null) { reader.End(); } } return(results); }
public IEnumerable <RGBA> EnRGBA() { PngChunkPLTE oplte = null; PngChunkTRNS otrns = null; // transparency metadata, can be null if (pngr.ImgInfo.Indexed) { oplte = pngr.GetMetadata().GetPLTE(); otrns = pngr.GetMetadata().GetTRNS(); } for (var row = 0; row < pngr.ImgInfo.Rows; row++) { var line = pngr.ReadRowInt(row); if (pngr.ImgInfo.Indexed) { var rgrgba = ImageLineHelper.Palette2rgb(line, oplte, otrns, null); for (var irgba = 0; irgba < rgrgba.Length;) { yield return(new RGBA { r = rgrgba[irgba++], g = rgrgba[irgba++], b = rgrgba[irgba++], a = (otrns != null ? rgrgba[irgba++] : 255), }); } } else { if (pngr.ImgInfo.Packed) { line = line.unpackToNewImageLine(); } for (var col = 0; col < pngr.ImgInfo.Cols; col++) { switch (pngr.ImgInfo.Channels) { case 1: yield return(new RGBA { r = Read8(col, line), g = Read8(col, line), b = Read8(col, line), }); break; case 2: yield return(new RGBA { r = Read8(col * 2, line), g = Read8(col * 2, line), b = Read8(col * 2, line), a = Read8(col * 2 + 1, line), }); break; case 3: yield return(new RGBA { r = Read8(col * 3, line), g = Read8(col * 3 + 1, line), b = Read8(col * 3 + 2, line), }); break; case 4: yield return(new RGBA { r = Read8(col * 4, line), g = Read8(col * 4 + 1, line), b = Read8(col * 4 + 2, line), a = Read8(col * 4 + 3, line), }); break; } } } } }