Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Windows.Forms;
- namespace RGZ {
- public partial class Form1 : Form {
- private class PCXTC {
- public readonly byte ID;
- public readonly byte Version;
- public readonly byte Coding;
- public readonly byte BitPerPixel;
- public readonly short XMin;
- public readonly short YMin;
- public readonly short XMax;
- public readonly short YMax;
- public readonly short HRes;
- public readonly short VRes;
- public readonly byte[] Pal256x;
- public readonly byte Reserved;
- public readonly byte Planes;
- public readonly short BytePerLine;
- public readonly short PaletteInfo;
- public readonly short HScreenSize;
- public readonly short VScreenSize;
- public readonly byte[] Filler;
- public readonly short Width;
- public readonly short Height;
- public readonly byte[] Pal256;
- public readonly byte[] Pixels;
- public readonly Bitmap bmp;
- public PCXTC() {
- Pal256x = new byte[48];
- Filler = new byte[54];
- Pixels = null;
- }
- public PCXTC(string FileName) {
- using (BinaryReader binReader = new BinaryReader(File.Open(FileName, FileMode.Open, FileAccess.Read))) {
- int totalSize = (int)binReader.BaseStream.Length;
- ID = binReader.ReadByte();
- Version = binReader.ReadByte();
- Coding = binReader.ReadByte();
- BitPerPixel = binReader.ReadByte();
- XMin = binReader.ReadInt16();
- YMin = binReader.ReadInt16();
- XMax = binReader.ReadInt16();
- YMax = binReader.ReadInt16();
- HRes = binReader.ReadInt16();
- VRes = binReader.ReadInt16();
- Pal256x = binReader.ReadBytes(48);
- Reserved = binReader.ReadByte();
- Planes = binReader.ReadByte();
- BytePerLine = binReader.ReadInt16();
- PaletteInfo = binReader.ReadInt16();
- HScreenSize = binReader.ReadInt16();
- VScreenSize = binReader.ReadInt16();
- Filler = binReader.ReadBytes(54);
- Width = (short)(XMax - XMin + 1);
- Height = (short)(YMax - YMin + 1);
- Pixels = new byte[Width * Height * 3];
- binReader.BaseStream.Seek(128, SeekOrigin.Begin);
- int totalData = totalSize - 769 - 128 * Planes;
- byte count = 0;
- byte data = 0;
- int pos = 0;
- for (int i = 0; i < Height; ++i) {
- for (int j = 0; j < Planes; ++j) {
- pos = 3 * Width * i + j;
- for (int k = 0; k < BytePerLine; ++k) {
- if (count == 0) {
- data = binReader.ReadByte();
- count = 1;
- if ((data & 0b11000000) == 0b11000000) {
- count = (byte)(data & 0b00111111);
- data = binReader.ReadByte();
- }
- }
- count--;
- if (k < Width) {
- Pixels[pos] = data;
- pos += 3;
- }
- }
- }
- }
- }
- bmp = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
- BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
- int padding = bmpData.Stride - 3 * Width;
- int counter = 0;
- unsafe {
- byte* ptr = (byte*)bmpData.Scan0;
- for (int i = 0; i < Height; ++i) {
- for (int j = 0; j < Width; ++j) {
- ptr[2] = Pixels[counter];
- ptr[1] = Pixels[counter + 1];
- ptr[0] = Pixels[counter + 2];
- counter += 3;
- ptr += 3;
- }
- ptr += padding;
- }
- }
- bmp.UnlockBits(bmpData);
- }
- }
- private class BMP256 {
- readonly byte ID;
- readonly byte Version;
- readonly byte Coding;
- readonly byte BitPerPixel;
- readonly short XMin;
- readonly short YMin;
- readonly short XMax;
- readonly short YMax;
- readonly short HRes;
- readonly short VRes;
- readonly byte[] Pal256x;
- readonly byte Reserved;
- readonly byte Planes;
- readonly short BytePerLine;
- readonly short PaletteInfo;
- readonly short HScreenSize;
- readonly short VScreenSize;
- readonly byte[] Filler;
- readonly short Width;
- readonly short Height;
- List<byte> PixelsRLE;
- List<byte> Pixels;
- List<Color> AllPixelsColor;
- public Bitmap bmp;
- public static int rgbTo8Bit(int r, int g, int b) {
- bool grayPossible = true;
- bool gray = false;
- float sep = 42.5f;
- while (grayPossible) {
- if (r < sep || g < sep || b < sep) {
- gray = r < sep && g < sep && b < sep;
- grayPossible = false;
- }
- sep += 42.5f;
- }
- if (gray) {
- return (int)Math.Round(232f + (r + g + b) / 33f);
- }
- else {
- return 16 + ((int)(6f * (r / 256f))) * 36 + ((int)(6f * (g / 256f))) * 6 + ((int)(6f * (b / 256f)));
- }
- }
- public BMP256() {
- Pal256x = new byte[48];
- Filler = new byte[54];
- }
- public BMP256(PCXTC TC, int delta) {
- ID = TC.ID;
- Version = 5;
- Coding = 1;
- BitPerPixel = 8;
- XMin = TC.XMin;
- YMin = TC.YMin;
- XMax = TC.XMax;
- YMax = TC.YMax;
- HRes = TC.HRes;
- VRes = TC.VRes;
- Pal256x = TC.Pal256x;
- Reserved = TC.Reserved;
- Planes = 1;
- BytePerLine = TC.BytePerLine;
- PaletteInfo = 1;
- HScreenSize = TC.HScreenSize;
- VScreenSize = TC.VScreenSize;
- Filler = TC.Filler;
- Width = TC.Width;
- Height = TC.Height;
- Pixels = new List<byte>();
- AllPixelsColor = new List<Color>();
- for (int i = 0; i < TC.Pixels.Length; i += 3) {
- AllPixelsColor.Add(Color.FromArgb(TC.Pixels[i], TC.Pixels[i + 1], TC.Pixels[i + 2]));
- }
- var groups = from s in AllPixelsColor
- group s by s into g
- select
- new { Stuff = g.Key, Count = g.Count() };
- List<KeyValuePair<Color, int>> Probabilities = groups.ToDictionary(g => g.Stuff, g => g.Count).Where(x => x.Value > 10).OrderByDescending(x => x.Value).ToList();
- Color[] Pallete = new Color[256];
- double Delta = delta;
- int totalcolorInd = 0;
- for (int i = 0; i < 256; ++i)
- {
- bool found = false;
- Color newColor = Probabilities[i].Key;
- for (int NewColorInd = totalcolorInd; NewColorInd < Probabilities.Count; NewColorInd += 1)
- {
- for (int OldColorInd = 0; OldColorInd < i; ++OldColorInd)
- {
- double DifferenceR = Math.Pow(Pallete[OldColorInd].R - Probabilities[NewColorInd].Key.R, 2);
- double DifferenceG = Math.Pow(Pallete[OldColorInd].G - Probabilities[NewColorInd].Key.G, 2);
- double DifferenceB = Math.Pow(Pallete[OldColorInd].B - Probabilities[NewColorInd].Key.B, 2);
- double OverallDiffence = DifferenceR + DifferenceG + DifferenceB;
- if (Delta <= OverallDiffence)
- {
- newColor = Probabilities[NewColorInd].Key;
- if (NewColorInd + 1 < Probabilities.Count)
- totalcolorInd = NewColorInd + 1;
- found = true;
- break;
- }
- }
- if (found)
- break;
- }
- Pallete[i] = newColor;
- }
- for (int i = 0; i < AllPixelsColor.Count; ++i)
- {
- double LowestDifference = double.MaxValue;
- byte ColorIndex = 0;
- for (int cIndex = 0; cIndex < 256; ++cIndex)
- {
- double DifferenceR = Math.Pow(Pallete[cIndex].R - AllPixelsColor[i].R, 2);
- double DifferenceG = Math.Pow(Pallete[cIndex].G - AllPixelsColor[i].G, 2);
- double DifferenceB = Math.Pow(Pallete[cIndex].B - AllPixelsColor[i].B, 2);
- double OverallDiffence = DifferenceR + DifferenceG + DifferenceB;
- if (OverallDiffence < LowestDifference)
- {
- ColorIndex = (byte)cIndex;
- LowestDifference = OverallDiffence;
- }
- }
- Pixels.Add(ColorIndex);
- }
- bmp = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed);
- ColorPalette newColorPallete = bmp.Palette;
- for (int i = 0; i < 256; ++i)
- newColorPallete.Entries[i] = Pallete[i];
- bmp.Palette = newColorPallete;
- Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
- BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
- List<byte> PixelsToOutput = new List<byte>();
- for (int i = 0; i < Pixels.Count; i += 2)
- PixelsToOutput.Add((byte)((byte)(Pixels[i] << 8) + Pixels[i + 1]));
- Marshal.Copy(Pixels.ToArray(), 0, bmpData.Scan0, Pixels.Count);
- bmp.UnlockBits(bmpData);
- }
- }
- PCXTC PicTC = new PCXTC();
- BMP256 Pic256 = new BMP256();
- public Form1() {
- InitializeComponent();
- }
- private void B_SelectFile_Click(object sender, EventArgs e) {
- using (OpenFileDialog ofg = new OpenFileDialog()) {
- ofg.Filter = "PCX Image (.pcx)|*.pcx";
- ofg.FilterIndex = 0;
- if (ofg.ShowDialog() == DialogResult.OK) {
- string FileName = ofg.FileName;
- textBox_Path.Text = FileName;
- PicTC = new PCXTC(FileName);
- pB_Before.Image = PicTC.bmp;
- }
- }
- }
- private void B_Convert_Click(object sender, EventArgs e) {
- if (PicTC.bmp != null)
- {
- Pic256 = new BMP256(PicTC, (int)numericUpDown1.Value);
- pB_After.Image = Pic256.bmp;
- }
- }
- private void button1_Click(object sender, EventArgs e)
- {
- if (Pic256.bmp != null)
- using (SaveFileDialog dialog = new SaveFileDialog())
- {
- dialog.Filter = "BMP Image|*.bmp";
- if (dialog.ShowDialog() == DialogResult.OK)
- Pic256.bmp.Save(dialog.FileName, ImageFormat.Bmp);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment