예제 #1
0
        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();
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        //---------------------------------------------------------------------
        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);
                }
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        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();
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        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;
                        }
                    }
                }
            }
        }