Click here to Skip to main content
15,885,908 members
Articles / Programming Languages / C#
Tip/Trick

Custom black and white Image Format

Rate me:
Please Sign up or sign in to vote.
4.00/5 (3 votes)
20 Nov 2022CPOL 4.7K   3   8
Custom black and white image format
This class was created to find a way to write/read PBM Image format.
C#
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Serialization.Formatters.Binary;
namespace Chico
{
    [Serializable]
    public sealed class CPBM
    {
        private bool[,] pixels;
        /// <summary>
        /// Represents a <see langword="null"/> <see cref="CPBM"/>.
        /// </summary>
        public static readonly CPBM Null = new CPBM(0, 0);
        private CPBM(int width, int height)
        {
            if (width <= 0 || height <= 0)
                return;
            this.pixels = new bool[width, height];
        }
        /// <summary>
        /// Load a <see cref="CPBM"/> from the specified stream.
        /// </summary>
        /// <returns>The cpbm from stream.</returns>
        /// <param name="stream">Stream.</param>
        public static CPBM Load(Stream stream)
        {
            BinaryFormatter decompressionFormatter = new BinaryFormatter();
            byte[] compressedBytes = null;
            using (MemoryStream compressionReader = new MemoryStream())
            {
                stream.CopyTo(compressionReader);
                compressedBytes = compressionReader.ToArray();
            }
            Array.Reverse(compressedBytes);
            using (MemoryStream decompressionStream = new MemoryStream(compressedBytes.Decompress()))
                return (CPBM)decompressionFormatter.Deserialize(decompressionStream);
        }
        /// <summary>
        /// Save this <see cref="CPBM"/> to the specified stream.
        /// </summary>
        /// <param name="stream">Stream.</param>
        public void Save(Stream stream)
        {
            byte[] cpbmData = null;
            using (MemoryStream cpbmWriter = new MemoryStream())
            {
                BinaryFormatter cpbmFormatter = new BinaryFormatter();
                cpbmFormatter.Serialize(cpbmWriter, this);
                cpbmData = cpbmWriter.ToArray();
            }
            byte[] compressedCpbm = cpbmData.Compress();
            Array.Reverse(compressedCpbm);
            stream.Write(compressedCpbm, 0, compressedCpbm.Length);
        }
        /// <summary>
        /// Gets or sets the level.
        /// </summary>
        /// <value>The level.</value>
        public int Level { get; set; }
        /// <summary>
        /// Gets the width of this <see cref="CPBM"/>.
        /// </summary>
        /// <value>The width.</value>
        public int Width => this.pixels.GetLength(0);
        /// <summary>
        /// Gets the height of this <see cref="CPBM"/>.
        /// </summary>
        /// <value>The height.</value>
        public int Height => this.pixels.GetLength(1);
        /// <summary>
        /// Gets the pixel at the specified coordinates of this <see cref="CPBM"/>.
        /// </summary>
        /// <returns><c>true</c>, if pixel was gotten, <c>false</c> otherwise.</returns>
        /// <param name="x">The x coordinate.</param>
        /// <param name="y">The y coordinate.</param>
        public bool GetPixel(int x, int y) => this.pixels[x, y];
        /// <summary>
        /// Sets the requested pixel at the specified coordinates.
        /// </summary>
        /// <param name="x">The x coordinate.</param>
        /// <param name="y">The y coordinate.</param>
        /// <param name="value">If set to <c>true</c> value.</param>
        public void SetPixel(int x, int y, bool value) => this.pixels[x, y] = value;
        private Color GetColor(int x, int y) => this.pixels[x, y] ? Color.White : Color.Black;
        /// <summary>
        /// Load a <see cref="CPBM"/> from the specified bitmap.
        /// </summary>
        /// <param name="bitmap">Bitmap.</param>
        /// <param name="useColorCorrectionProfile">If set to <c>true</c> use Color Correction Profile.</param>
        public void FromBitmap(Bitmap bitmap, bool useColorCorrectionProfile = false)
        {
            if (bitmap == null)
                return;
            this.pixels = new bool[bitmap.Width, bitmap.Height];
            for (int x = 0; x < bitmap.Width; x++)
            {
                for (int y = 0; y < bitmap.Height; y++)
                {
                    Color c = bitmap.GetPixel(x, y);
                    bool adjust = (c.R + c.G + c.B) >= Level;
                    if (!useColorCorrectionProfile)
                        this.SetPixel(x, y, !adjust);
                    else
                        this.SetPixel(x, y, adjust);
                }
            }
        }
        /// <summary>
        /// Saves a copy of this <see cref="CPBM"/> as a <see cref="Bitmap"/>.
        /// </summary>
        /// <param name="path">Path.</param>
        public void ToBitmap(string path)
        {
            try
            {
                this.ToBitmap().Save(path);
            }
            catch
            {
                return;
            }
        }
        public static explicit operator Bitmap(CPBM cPBM) => cPBM?.ToBitmap();
        private Bitmap ToBitmap()
        {
            Bitmap bitmap = new Bitmap(Width, Height);
            for (int x = 0; x < bitmap.Width; x++)
            {
                for (int y = 0; y < bitmap.Height; y++)
                {
                    bitmap.SetPixel(x, y, this.GetColor(x, y));
                }
            }
            using (MemoryStream ms = new MemoryStream())
            {
                bitmap.Save(ms, ImageFormat.Gif);
                ms.Seek(0, SeekOrigin.Begin);
                return (Bitmap)Image.FromStream(ms);
            }
        }
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I do not claim to be wrong! I just rarely ever write.

Comments and Discussions

 
PraiseMy vote of 5 Pin
Stylianos Polychroniadis24-Nov-22 13:51
Stylianos Polychroniadis24-Nov-22 13:51 
GeneralRe: My vote of 5 Pin
charles henington25-Nov-22 0:51
charles henington25-Nov-22 0:51 
QuestionPlease describe the format Pin
YDaoust22-Nov-22 2:44
YDaoust22-Nov-22 2:44 
AnswerRe: Please describe the format Pin
charles henington22-Nov-22 15:22
charles henington22-Nov-22 15:22 
GeneralRe: Please describe the format Pin
YDaoust22-Nov-22 20:45
YDaoust22-Nov-22 20:45 
GeneralRe: Please describe the format Pin
charles henington22-Nov-22 23:44
charles henington22-Nov-22 23:44 
GeneralRe: Please describe the format Pin
YDaoust23-Nov-22 3:40
YDaoust23-Nov-22 3:40 
GeneralRe: Please describe the format Pin
charles henington23-Nov-22 18:21
charles henington23-Nov-22 18:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.