创建此类是为了找到一种写入/读取PBM图像格式的方法。
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);
}
}
}
}
https://www.codeproject.com/Tips/5347554/Custom-Black-and-White-Image-Format