我从这里尝试了几个例子,但没有发现任何可行的例子。
我需要能够将彩色图像转换为黑白图像,以便我可以将这些数据发送到热敏打印机。
将图像从彩色变为黑白似乎是麻烦,因为我在C#库中找不到任何方法。
我正在测试的图像是PixelFormat.Format32bppArgb,我相信我想将其转换为PixelFormat.Format1bppIndexed
编辑:不知道如何让它更清晰。我不想灰度我想黑白这就是“PixelFormst.Format1bppIndexed”
答案 0 :(得分:1)
Imagemagick可以通过各种方法将图像转换为黑白图像,包括抖动(-dither)和有序抖动(-ordered-dither)。我通常使用命令行界面,但有一个名为magick.net的C#绑定可能会尝试。请参阅magick.codeplex.com。
有些例子,请参阅codegolf.stackexchange.com
上的此问答答案 1 :(得分:1)
您可以使用安装在大多数Linux发行版上的ImageMagick,并且可以免费获得OSX(理想情况下通过homebrew
)以及here中的Windows。
如果从这个平滑的灰度渐变开始:
在命令行中,您可以将此用于Floyd-Steinberg抖动:
convert grey.png -dither FloydSteinberg -monochrome fs.bmp
或者,这适用于Riemersma抖动:
convert grey.png -dither Riemersma -monochrome riem.bmp
格伦所指的有序抖动可以像这样使用不同的磁贴选项:
convert grey.png -ordered-dither o8x8 -monochrome od8.bmp
convert grey.png -ordered-dither o2x2 -monochrome od2.bmp
格式检查显示它是1bpp,带有双色调色板:
identify -verbose riem.bmp
Image: riem.bmp
Format: BMP (Microsoft Windows bitmap image)
Class: PseudoClass
Geometry: 262x86+0+0
Units: PixelsPerCentimeter
Type: Bilevel
Base type: Bilevel <--- 1 bpp
Endianess: Undefined
Colorspace: Gray
Depth: 1-bit <--- 1 bpp
Channel depth:
gray: 1-bit
Channel statistics:
Pixels: 22532
Gray:
min: 0 (0)
max: 1 (1)
mean: 0.470486 (0.470486)
standard deviation: 0.499128 (0.499128)
kurtosis: -1.98601
skewness: 0.118261
entropy: 0.997485
Colors: 2
Histogram:
11931: ( 0, 0, 0) #000000 gray(0)
10601: (255,255,255) #FFFFFF gray(255)
Colormap entries: 2
Colormap:
0: ( 0, 0, 0) #000000 gray(0) <--- colourmap has only black...
1: (255,255,255) #FFFFFF gray(255) <--- ... and white
如果你从这样的彩色图像开始:
并按此处理:
convert colour.png -ordered-dither o8x8 -monochrome od8.bmp
你会得到这个
正如Glenn所说,ImageMagick有C#绑定 - 或者您可以在批处理文件中使用上述命令,或使用system()
调用的C#等效执行上述ImageMagick命令。
答案 2 :(得分:1)
您可以使用此代码将图像转换为黑白图像。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Converting_Image_to__Black_and_White
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static int siyahbeyazsinirnoktasi=0;
public static string DosyaYolu = "";
#region resim üzerinde işlemler yapma (siyah beyaz)
Bitmap BlackandWhite(Bitmap Goruntu)
{
Bitmap yeniGoruntu = new Bitmap(Goruntu.Width,
Goruntu.Height);//Bitmap sınıfımızı oluşturduk.
double toplampikselsayisi = Goruntu.Width * Goruntu.Height;
int GriTonlama;
for (int i = 0; i < Goruntu.Width; i++)//resmi yatay olarak
taramak için
{
for (int j = 0; j < Goruntu.Height; j++)//resmi dikey olarak
taramak için
{
Color Pixel = Goruntu.GetPixel(i, j);//color sınıfını ile
pixel rengini alıyoruz.
GriTonlama = (Pixel.R + Pixel.G + Pixel.B) / 3;//almış
olduğumuz renk değerini gri tona çevirmek için kullanmamız gereken
formül.
if (GriTonlama < siyahbeyazsinirnoktasi)
{
yeniGoruntu.SetPixel(i, j, Color.FromArgb(0, 0,
0));//yeni görüntümüze gri tonlamadaki pixel değerini veriyoruz.
}
if (GriTonlama >= siyahbeyazsinirnoktasi)
{
yeniGoruntu.SetPixel(i, j, Color.FromArgb(255, 255,
255));//yeni görüntümüze gri tonlamadaki pixel değerini veriyoruz.
}
}
}
return yeniGoruntu;
}
#endregion
private void btnLoadImage_Click(object sender, EventArgs e)
{
FolderBrowserDialog Klasor = new FolderBrowserDialog();
openFileDialog1.Title = "Resimdosyası seçiniz.";
openFileDialog1.Filter = "Image files (*.jpg)|*.jpg|Tüm
dosyalar(*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
DosyaYolu = openFileDialog1.FileName;
var dosyaboyutu = new FileInfo(DosyaYolu).Length;
if (dosyaboyutu <= 500000)
{
pictureBox1.Image = new
Bitmap(openFileDialog1.OpenFile());
btnConvertBlackandWhite.Enabled = true;
label1.Visible = true;
label2.Visible= true;
label3.Visible = true;
label4.Visible = true;
label5.Visible = true;
label6.Visible = true;
trackBar1.Visible = true;
}
else
{
MessageBox.Show("Seçtiğiniz resim boyutu 500 KB'nın
altında olmalıdır.");
}
}
}
private void btnConvertBlackandWhite_Click(object sender, EventArgs
e)
{
pictureBox1.Image = BlackandWhite(new Bitmap(DosyaYolu));
btnSave.Enabled = true;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
siyahbeyazsinirnoktasi = trackBar1.Value ;
label3.Text = Convert.ToString(siyahbeyazsinirnoktasi);
}
private void Form1_Load(object sender, EventArgs e)
{
label3.Text = "130";
siyahbeyazsinirnoktasi = 130;
}
private void btnSave_Click(object sender, EventArgs e)
{
{
Image pngoptikform = new Bitmap(pictureBox1.Image);
SaveFileDialog sf = new SaveFileDialog();//yeni bir kaydetme
diyaloğu oluşturuyoruz.
sf.Filter = "Image file (Jpg dosyası (*.jpg)|*.jpg ";//.bmp
veya .jpg olarak kayıt imkanı sağlıyoruz.
sf.Title = "Kayıt";//diğaloğumuzun başlığını belirliyoruz.
sf.CheckPathExists = true;
sf.DefaultExt = "jpg";
sf.FilterIndex = 1;
DialogResult sonuc = sf.ShowDialog();
if (sonuc == DialogResult.OK)
{
if (sf.FilterIndex == 1)
{
pngoptikform.Save(sf.FileName);
System.Diagnostics.Process.Start(sf.FileName);
}
}
}
}
}
}
答案 3 :(得分:0)
我相信你可以通过一个像样的抖动算法获得相当不错的结果。这里有类似的帖子,请看看它是否对您有所帮助:
答案 4 :(得分:0)
我个人分两步完成这项工作:
我之前已经解释过的第一步,this answer。 (您可能希望使用更详细的抖动方法,如此处的其他答案中所述,但即使这样,其方法也需要答案将图像转换和操作为字节数组。)
详细说明的基本方法是:
width * height
个字节)。将您的照片转换为黑白 8位图像。现在,我们需要做的就是获得一个 1位图像,在最后一步之前迈出新的一步,我们将8位数据压缩为1位数据,然后进行最后的调用改为使用BuildImage
PixelFormat.Format1bppIndexed
功能。
这是将图像缩小到较低位长度的功能。它需要原始图像数据和步幅,并将返回转换后的图像数据和新步幅。
注意,我不确定数据字节内的位顺序对于普通的dotNet 1位图像是什么,因为我只使用此函数来转换自定义游戏文件格式,因此您只需要测试它以查看您需要在bigEndian
参数中给出的内容。如果给出错误的值,则每个8像素的列将被左右镜像,因此在结果中应该是显而易见的。
/// <summary>
/// Converts given raw image data for a paletted 8-bit image to lower amount of bits per pixel.
/// </summary>
/// <param name="data8bit">The eight bit per pixel image data</param>
/// <param name="width">The width of the image</param>
/// <param name="height">The height of the image</param>
/// <param name="bitsLength">The new amount of bits per pixel</param>
/// <param name="bigEndian">True if the bits in the new image data are to be stored as big-endian.</param>
/// <param name="stride">Stride used in the original image data. Will be adjusted to the new stride value.</param>
/// <returns>The image data converted to the requested amount of bits per pixel.</returns>
public static Byte[] ConvertFrom8Bit(Byte[] data8bit, Int32 width, Int32 height, Int32 bitsLength, Boolean bigEndian, ref Int32 stride)
{
Int32 parts = 8 / bitsLength;
// Amount of bytes to write per width. This rounds the bits up to the nearest byte.
Int32 newStride = ((bitsLength * width) + 7) / 8;
// Bit mask for reducing original data to actual bits maximum.
// Should not be needed if data is correct, but eh.
Int32 bitmask = (1 << bitsLength) - 1;
Byte[] dataXbit = new Byte[newStride * height];
// Actual conversion porcess.
for (Int32 y = 0; y < height; y++)
{
for (Int32 x = 0; x < width; x++)
{
// This will hit the same byte multiple times
Int32 indexXbit = y * newStride + x / parts;
// This will always get a new index
Int32 index8bit = y * stride + x;
// Amount of bits to shift the data to get to the current pixel data
Int32 shift = (x % parts) * bitsLength;
// Reversed for big-endian
if (bigEndian)
shift = 8 - shift - bitsLength;
// Get data, reduce to bit rate, shift it and store it.
dataXbit[indexXbit] |= (Byte)((data8bit[index8bit] & bitmask) << shift);
}
}
stride = newStride;
return dataXbit;
}
答案 5 :(得分:-1)
显示颜色的术语称为灰度:
快速搜索:color to gray scale converter c#
产生了以下网站:http://www.codeproject.com/Questions/315939/How-To-Convert-Grayscale-Image-to-Color-Image-in-c