/// <summary> /// Main constructor for PNGFile. /// </summary> /// <param name="path">Path to the PNG file to be loaded.</param> public PNGFile(string path) { originalFile = path; var reader = FileHelper.CreatePngReader(path); if (reader.ImgInfo.BitDepth != 8 || reader.ImgInfo.Channels < 3) { throw new ArgumentException("The PNG file must be an 24/32 bit PNG file, 8bit channels and RGB/A"); } this.ImgInfo = reader.ImgInfo; reader.ShouldCloseStream = true; hasAlpha = reader.ImgInfo.Alpha; for (var x = 0; x < reader.ImgInfo.Rows; x++) { PNGPixel[] line = new PNGPixel[reader.ImgInfo.Cols]; byte[] scanLine = reader.ReadRowByte(x).ScanlineB; int bytesPerPixel = hasAlpha ? 4 : 3; int byteCount = 0; int pixelCount = 0; PNGPixel curPixel = new PNGPixel(); for (var y = 0; y < scanLine.Length; y++) { byteCount++; if (byteCount > bytesPerPixel || y == (scanLine.Length - 1)) { line[pixelCount++] = curPixel; byteCount = 1; curPixel = new PNGPixel(); } if (byteCount == 1) { curPixel.Red = scanLine[y]; } else if (byteCount == 2) { curPixel.Green = scanLine[y]; } else if (byteCount == 3) { curPixel.Blue = scanLine[y]; } else if (byteCount == 4) { curPixel.Alpha = scanLine[y]; } } lines.Add(line); } reader.End(); reader = null; }
private static byte[] ReadBytes(PNGFile file, PNGScrambler scrambler, int count, int skip = 0) { scrambler.Reset(); List <byte> bits = new List <byte>(); int numBitsToRead = count * 8; int pixelsToRead = numBitsToRead / 6 + ((numBitsToRead / 6.0) % 1.0 != 0 ? 1 : 0); int pixelsToSkip = (skip * 8) / 6; //int bitPairsToThrowaway = pixelsToSkip == 0 ? 0 : (6 - ((skip * 8) % 6)) / 2; int bitPairsToThrowaway = ((skip * 8) % 6) / 2; if (bitPairsToThrowaway == 2) { pixelsToRead++; } for (var x = 0; x < pixelsToSkip; x++) { scrambler.GetPixel(); } for (var x = 0; x < pixelsToRead; x++) { PNGPixel p = scrambler.GetPixel(); bits.Add((byte)(p.Red & 0x03)); bits.Add((byte)(p.Green & 0x03)); bits.Add((byte)(p.Blue & 0x03)); } for (var x = 0; x < bitPairsToThrowaway; x++) { bits.RemoveAt(0); } return(BitsToBytes(bits)); }
private static void EmbedData(byte[] data, PNGScrambler scrambler) { PNGPixel pix = null; List <byte> bits = BytesToBits(data); int channel = 3; for (var x = 0; x < bits.Count; x++) { if (channel == 3) { pix = scrambler.GetPixel(); channel = 0; } switch (channel) { case 0: pix.Red &= 0xFC; pix.Red |= bits[x]; break; case 1: pix.Green &= 0xFC; pix.Green |= bits[x]; break; case 2: pix.Blue &= 0xFC; pix.Blue |= bits[x]; break; } channel++; } }