Reads a PNG image, line by line
The typical reading sequence is as follows: 1. At construction time, the header and IHDR chunk are read (basic image info) 2 (Optional) you can set some global options: UnpackedMode CrcCheckDisabled 3. (Optional) If you call GetMetadata() or or GetChunksLisk() before reading the pixels, the chunks before IDAT are automatically loaded and available 4a. The rows are read, one by one, with the ReadRowXXX methods: (ReadRowInt() , ReadRowByte(), etc) in order, from 0 to nrows-1 (you can skip or repeat rows, but not go backwards) 4b. Alternatively, you can read all rows, or a subset, in a single call: see ReadRowsInt(), ReadRowsByte() In general this consumes more memory, but for interlaced images this is equally efficient, and more so if reading a small subset of rows. 5. Read of the last row automatically loads the trailing chunks, and ends the reader. 6. End() forcibly finishes/aborts the reading and closes the stream
        private void btnOpen_Click( object sender, RoutedEventArgs e )
        {
            CommonOpenFileDialog openDialog = new CommonOpenFileDialog();
              openDialog.ShowPlacesList = true;
              openDialog.Multiselect = false;
              openDialog.IsFolderPicker = false;
              openDialog.AddToMostRecentlyUsedList = true;
              openDialog.Filters.Add( new CommonFileDialogFilter( "PNG images", "*.png" ) );
              if ( openDialog.ShowDialog( this ) == CommonFileDialogResult.Ok ) {
            soureFilePath = openDialog.FileName;
            // get comment meta
            using ( FileStream fileStream = new FileStream( soureFilePath, FileMode.Open, FileAccess.Read ) ) {
              pngReader = new PngReader( fileStream );
              // 参考自Hjg.Pngcs的SampleCustomChunk项目
              // get last line: this forces loading all chunks
              pngReader.ReadChunksOnly();
              tblkComment.Text = pngReader.GetMetadata().GetTxtForKey( Key_SemanticInfo );
              pngReader.End();
              fileStream.Close();
            }

            image.BeginInit();
            image.Source = new BitmapImage( new Uri( soureFilePath ) );
            image.EndInit();
              }
        }
Beispiel #2
0
        //---------------------------------------------------------------------
        public bool load(byte[] data)
        {
            MemoryStream ms = new MemoryStream(data);
            mPngReader = new PngReader(ms);

            return (mPngReader != null);
        }
Beispiel #3
0
        public static string[,] buildMatrix(Dictionary<Color, string> dictionary, PngReader reader)
        {
            ImageInfo info = reader.ImgInfo;
            var matrix = new string[info.Cols, info.Rows];

            for (int i = 0; i < info.Rows; i++) {
            ImageLine line = reader.ReadRow(i);
            int[] lineInts = line.Scanline;

            for (int j = 0, col = 0; j < lineInts.Length; j += info.Channels, col++) {
                int red = lineInts[j];
                int green = lineInts[j + 1];
                int blue = lineInts[j + 2];
                int alpha = 255;

                if (info.Channels == 4) {
                    alpha = lineInts[j + 3];
                }

                Color color = new Color(red / 255f, green / 255f, blue / 255f, alpha / 255f);
                string val;
                if (dictionary.TryGetValue(color, out val)) {
                    matrix[col, i] = val;
                }
            }
            }

            return matrix;
        }
Beispiel #4
0
        public static string[,] buildMatrix(Stream dictionaryStream, Stream mapStream)
        {
            var dictionary = readDictionary(dictionaryStream);
            PngReader reader = new PngReader(mapStream);

            return buildMatrix(dictionary, reader);
        }
Beispiel #5
0
 public static void fatalError(String s, PngReader png1)
 {
     try {
         png1.End();
     } catch (Exception ) {
     }
     throw new PngjException(s);
 }
Beispiel #6
0
        //---------------------------------------------------------------------
        public bool load(string file_name)
        {
            string path_png = file_name.ToLower();
            if (!path_png.EndsWith(".png"))
            {
                path_png += ".png";
            }

            mPngReader = FileHelper.CreatePngReader(path_png);

            return (mPngReader != null);
        }
Beispiel #7
0
 /// <summary>
   /// copy chunks from reader - copy_mask : see ChunksToWrite.COPY_XXX
   /// If we are after idat, only considers those chunks after IDAT in PngReader
   /// TODO: this should be more customizable
   /// </summary>
   ///
   private void CopyChunks(PngReader reader, int copy_mask, bool onlyAfterIdat) {
       bool idatDone = CurrentChunkGroup >= ChunksList.CHUNK_GROUP_4_IDAT;
       if (onlyAfterIdat && reader.CurrentChunkGroup < ChunksList.CHUNK_GROUP_6_END) throw new PngjException("tried to copy last chunks but reader has not ended");
       foreach (PngChunk chunk in reader.GetChunksList().GetChunks()) {
           int group = chunk.ChunkGroup;
           if (group < ChunksList.CHUNK_GROUP_4_IDAT && idatDone)
               continue;
           bool copy = false;
           if (chunk.Crit) {
               if (chunk.Id.Equals(ChunkHelper.PLTE, StringComparison.InvariantCultureIgnoreCase)) {
                   if (ImgInfo.Indexed && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_PALETTE))
                       copy = true;
                   if (!ImgInfo.Greyscale && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALL))
                       copy = true;
               }
           } else { // ancillary
               bool text = chunk is PngChunkTextVar;
               bool safe = chunk.Safe;
               // notice that these if are not exclusive
               if (ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALL))
                   copy = true;
               if (safe && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALL_SAFE))
                   copy = true;
               if (chunk.Id.Equals(ChunkHelper.tRNS, StringComparison.InvariantCultureIgnoreCase)
                       && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_TRANSPARENCY))
                   copy = true;
               if (chunk.Id.Equals(ChunkHelper.pHYs, StringComparison.InvariantCultureIgnoreCase) && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_PHYS))
                   copy = true;
               if (text && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_TEXTUAL))
                   copy = true;
               if (ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALMOSTALL)
                       && !(ChunkHelper.IsUnknown(chunk) || text || chunk.Id.Equals(ChunkHelper.hIST, StringComparison.InvariantCultureIgnoreCase) || chunk.Id.Equals(ChunkHelper.tIME, StringComparison.InvariantCultureIgnoreCase)))
                   copy = true;
               if (chunk is PngChunkSkipped)
                   copy = false;
           }
           if (copy)
             chunksList.Queue(PngChunk.CloneChunk(chunk, ImgInfo));
       }
   }
 public static void InitCrcForTests(PngReader pngr)
 {
     pngr.InitCrctest();
 }
Beispiel #9
0
 public void CopyChunksLast(PngReader reader, int copy_mask)
 {
     CopyChunks(reader, copy_mask, true);
 }
Beispiel #10
0
 public void CopyChunksFirst(PngReader reader, int copy_mask)
 {
     CopyChunks(reader, copy_mask, false);
 }
 public static void InitCrcForTests(PngReader pngr)
 {
     pngr.InitCrctest();
 }
 public static long GetCrctestVal(PngReader pngr)
 {
     return pngr.GetCrctestVal();
 }
    bool ReadImage( PngReader _png )
    {
        /*
        ImageLine line = pngr.ReadRowInt( y );
        int[] scanline = line.Scanline;

        string l = "";
        for( int x=0; x<scanline.Length; x++ )
        {
            int ci = scanline[ x ];
            l += ci.ToString() + ",";
        }

        Debug.Log ("line " + y + ": " + l );
        */

        int x,y;
        for( y=0; y<m_height; y++ )
        {
            ImageLine line = _png.ReadRowByte( y );
            //byte[] lineBytes = _png.ReadRowByte( y );
            byte[] lineBytes = line.ScanlineB;// GetScanlineInt();

            for( x=0; x<m_width; x++ )
            {
                byte src_c = lineBytes[ x ];
                byte remapped_c = src_c;
                if( m_config.m_colorRemapSourceToDest.ContainsKey( (int)src_c ))
                    remapped_c = (byte)m_config.m_colorRemapSourceToDest[ src_c ];
                m_colorUsed[ remapped_c ] = true;

                int dst_i = (y*m_width)+x;
                m_image[ dst_i ] = remapped_c;
            }
        }

        return true;
    }
Beispiel #14
0
        /// <summary>
        /// copy chunks from reader - copy_mask : see ChunksToWrite.COPY_XXX
        /// If we are after idat, only considers those chunks after IDAT in PngReader
        /// TODO: this should be more customizable
        /// </summary>
        ///
        private void CopyChunks(PngReader reader, int copy_mask, bool onlyAfterIdat)
        {
            if (reader is null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var idatDone = CurrentChunkGroup >= ChunksList.CHUNK_GROUP_4_IDAT;

            if (onlyAfterIdat && reader.CurrentChunkGroup < ChunksList.CHUNK_GROUP_6_END)
            {
                throw new PngjException("tried to copy last chunks but reader has not ended");
            }

            foreach (var chunk in reader.GetChunksList().Chunks)
            {
                var group = chunk.ChunkGroup;
                if (group < ChunksList.CHUNK_GROUP_4_IDAT && idatDone)
                {
                    continue;
                }

                var copy = false;
                if (chunk.Crit)
                {
                    if (chunk.Id.Equals(ChunkHelper.PLTE, StringComparison.Ordinal))
                    {
                        if (ImgInfo.Indexed && ChunkHelper.MaskMatch(copy_mask, ChunkCopyBehaviour.COPY_PALETTE))
                        {
                            copy = true;
                        }

                        if (!ImgInfo.Greyscale && ChunkHelper.MaskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALL))
                        {
                            copy = true;
                        }
                    }
                }
                else
                { // ancillary
                    var text = (chunk is AbstractPngChunkTextVar);
                    var safe = chunk.Safe;
                    // notice that these if are not exclusive
                    if (ChunkHelper.MaskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALL))
                    {
                        copy = true;
                    }

                    if (safe && ChunkHelper.MaskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALL_SAFE))
                    {
                        copy = true;
                    }

                    if (chunk.Id.Equals(ChunkHelper.tRNS, StringComparison.Ordinal) &&
                        ChunkHelper.MaskMatch(copy_mask, ChunkCopyBehaviour.COPY_TRANSPARENCY))
                    {
                        copy = true;
                    }

                    if (chunk.Id.Equals(ChunkHelper.pHYs, StringComparison.Ordinal) &&
                        ChunkHelper.MaskMatch(copy_mask, ChunkCopyBehaviour.COPY_PHYS))
                    {
                        copy = true;
                    }

                    if (text &&
                        ChunkHelper.MaskMatch(copy_mask, ChunkCopyBehaviour.COPY_TEXTUAL))
                    {
                        copy = true;
                    }

                    if (((ChunkHelper.MaskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALMOSTALL) &&
                          !ChunkHelper.IsUnknown(chunk)) ||
                         text ||
                         chunk.Id.Equals(ChunkHelper.hIST, StringComparison.Ordinal) ||
                         chunk.Id.Equals(ChunkHelper.tIME, StringComparison.Ordinal)))
                    {
                        copy = true;
                    }

                    if (chunk is PngChunkSkipped)
                    {
                        copy = false;
                    }
                }

                if (copy)
                {
                    _ = chunksList.Queue(AbstractPngChunk.CloneChunk(chunk, ImgInfo));
                }
            }
        }
Beispiel #15
0
 public void CopyChunksFirst(PngReader reader, int copy_mask)
 {
     CopyChunks(reader, copy_mask, onlyAfterIdat: false);
 }
Beispiel #16
0
 public void CopyChunksLast( PngReader reader, int copy_mask )
 {
     CopyChunks ( reader, copy_mask, true );
 }
Beispiel #17
0
 public void CopyChunksLast(PngReader reader, int copy_mask)
 {
     CopyChunks(reader, copy_mask, onlyAfterIdat: true);
 }
        private void btnSave_Click( object sender, RoutedEventArgs e )
        {
            CommonSaveFileDialog saveDialog = new CommonSaveFileDialog();
              saveDialog.ShowPlacesList = true;
              saveDialog.AddToMostRecentlyUsedList = true;
              saveDialog.Filters.Add( new CommonFileDialogFilter( "PNG images", "*.png" ) );
              saveDialog.DefaultFileName = DateTime.Now.ToString( "yyyyMMddhhmmss" ) + ".png";
              if ( saveDialog.ShowDialog( this ) == CommonFileDialogResult.Ok ) {
            using ( FileStream newFileStream = new FileStream( saveDialog.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite ),
              oldFileStream = new FileStream( soureFilePath, FileMode.Open, FileAccess.Read ) ) {
            string semanticInfo = @"
            sky: blue sky.
            heart: cloud heart.
            Meaning: It means love|爱|❤.
                ";

              ////// Reference: http://code.google.com/p/pngcs/wiki/Overview

              // get decoder
              pngReader = new PngReader( oldFileStream );
              // create encoder
              pngWriter = new PngWriter( newFileStream, pngReader.ImgInfo );
              // copy
              int chunkBehav = Hjg.Pngcs.Chunks.ChunkCopyBehaviour.COPY_ALL; // tell to copy all 'safe' chunks
              pngWriter.CopyChunksFirst( pngReader, chunkBehav );          // copy some metadata from reader
              int channels = pngReader.ImgInfo.Channels;
              if ( channels < 3 )
            throw new Exception( "This example works only with RGB/RGBA images" );
              for ( int row = 0; row < pngReader.ImgInfo.Rows; row++ ) {
            ImageLine l1 = pngReader.ReadRow( row ); // format: RGBRGB... or RGBARGBA...
            pngWriter.WriteRow( l1, row );
              }
              pngWriter.CopyChunksLast( pngReader, chunkBehav ); // metadata after the image pixels? can happen

              // app info
              pngWriter.GetMetadata().SetText( Hjg.Pngcs.Chunks.PngChunkTextVar.KEY_Software, "Semantic Image" );
              // semantic info
              Hjg.Pngcs.Chunks.PngChunk chunk = pngWriter.GetMetadata().SetText( Key_SemanticInfo, semanticInfo, false, false );
              chunk.Priority = true;

              pngWriter.End(); // dont forget this
              pngReader.End();

              oldFileStream.Close();
              newFileStream.Close();
            }
              }
        }
Beispiel #19
0
        //---------------------------------------------------------------------
        public bool load(Stream stream)
        {
            mPngReader = new PngReader(stream);

            return (mPngReader != null);
        }
Beispiel #20
0
 public void CopyChunksFirst( PngReader reader, int copy_mask )
 {
     CopyChunks ( reader, copy_mask, false );
 }
 public static long GetCrctestVal(PngReader pngr)
 {
     return(pngr.GetCrctestVal());
 }
Beispiel #22
0
 private void CopyChunks( PngReader reader, int copy_mask, bool onlyAfterIdat )
 {
     bool idatDone = CurrentChunkGroup >= ChunksList.CHUNK_GROUP_4_IDAT;
     if ( onlyAfterIdat && reader.CurrentChunkGroup < ChunksList.CHUNK_GROUP_6_END ) throw new PngjException ( "tried to copy last chunks but reader has not ended" );
     foreach ( PngChunk chunk in reader.GetChunksList ().GetChunks () )
     {
         int group = chunk.ChunkGroup;
         if ( group < ChunksList.CHUNK_GROUP_4_IDAT && idatDone )
             continue;
         bool copy = false;
         if ( chunk.Crit )
         {
             if ( chunk.Id.Equals ( ChunkHelper.PLTE ) )
             {
                 if ( ImgInfo.Indexed && ChunkHelper.maskMatch ( copy_mask, ChunkCopyBehaviour.COPY_PALETTE ) )
                     copy = true;
                 if ( !ImgInfo.Greyscale && ChunkHelper.maskMatch ( copy_mask, ChunkCopyBehaviour.COPY_ALL ) )
                     copy = true;
             }
         }
         else
         {
             bool text = ( chunk is PngChunkTextVar );
             bool safe = chunk.Safe;
             if ( ChunkHelper.maskMatch ( copy_mask, ChunkCopyBehaviour.COPY_ALL ) )
                 copy = true;
             if ( safe && ChunkHelper.maskMatch ( copy_mask, ChunkCopyBehaviour.COPY_ALL_SAFE ) )
                 copy = true;
             if ( chunk.Id.Equals ( ChunkHelper.tRNS )
                     && ChunkHelper.maskMatch ( copy_mask, ChunkCopyBehaviour.COPY_TRANSPARENCY ) )
                 copy = true;
             if ( chunk.Id.Equals ( ChunkHelper.pHYs ) && ChunkHelper.maskMatch ( copy_mask, ChunkCopyBehaviour.COPY_PHYS ) )
                 copy = true;
             if ( text && ChunkHelper.maskMatch ( copy_mask, ChunkCopyBehaviour.COPY_TEXTUAL ) )
                 copy = true;
             if ( ChunkHelper.maskMatch ( copy_mask, ChunkCopyBehaviour.COPY_ALMOSTALL )
                     && !( ChunkHelper.IsUnknown ( chunk ) || text || chunk.Id.Equals ( ChunkHelper.hIST ) || chunk.Id
                             .Equals ( ChunkHelper.tIME ) ) )
                 copy = true;
             if ( chunk is PngChunkSkipped )
                 copy = false;
         }
         if ( copy )
         {
             chunksList.Queue ( PngChunk.CloneChunk ( chunk, ImgInfo ) );
         }
     }
 }
Beispiel #23
0
        public void CopyChunks(PngReader reader, int copy_mask, bool onlyAfterIdat)
        {
            bool flag = CurrentChunkGroup >= 4;

            if (onlyAfterIdat && reader.CurrentChunkGroup < 6)
            {
                throw new PngjException("tried to copy last chunks but reader has not ended");
            }
            foreach (PngChunk chunk in reader.GetChunksList().GetChunks())
            {
                if (chunk.ChunkGroup >= 4 || !flag)
                {
                    bool flag2 = false;
                    if (chunk.Crit)
                    {
                        if (chunk.Id.Equals("PLTE"))
                        {
                            if (ImgInfo.Indexed && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_PALETTE))
                            {
                                flag2 = true;
                            }
                            if (!ImgInfo.Greyscale && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALL))
                            {
                                flag2 = true;
                            }
                        }
                    }
                    else
                    {
                        bool flag3 = chunk is PngChunkTextVar;
                        bool safe  = chunk.Safe;
                        if (ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALL))
                        {
                            flag2 = true;
                        }
                        if (safe && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALL_SAFE))
                        {
                            flag2 = true;
                        }
                        if (chunk.Id.Equals("tRNS") && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_TRANSPARENCY))
                        {
                            flag2 = true;
                        }
                        if (chunk.Id.Equals("pHYs") && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_PHYS))
                        {
                            flag2 = true;
                        }
                        if (flag3 && ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_TEXTUAL))
                        {
                            flag2 = true;
                        }
                        if (ChunkHelper.maskMatch(copy_mask, ChunkCopyBehaviour.COPY_ALMOSTALL) && !(ChunkHelper.IsUnknown(chunk) | flag3) && !chunk.Id.Equals("hIST") && !chunk.Id.Equals("tIME"))
                        {
                            flag2 = true;
                        }
                        if (chunk is PngChunkSkipped)
                        {
                            flag2 = false;
                        }
                    }
                    if (flag2)
                    {
                        chunksList.Queue(PngChunk.CloneChunk(chunk, ImgInfo));
                    }
                }
            }
        }