C# MWNumericArray(或字节[,])以格式化1BPindexed图像
我正在尝试将MatlabC# MWNumericArray(或字节[,])以格式化1BPindexed图像,c#,image,matlab,bitmap,C#,Image,Matlab,Bitmap,我正在尝试将MatlabMWNumericArray转换为黑白图片(而不是灰度)。起初,我尝试将2D字节数组转换为1D字节数组,然后将其复制到BitmapData对象并在位图中进行转换,但没有成功,因为我在尝试操作此数据时肯定犯了几个错误 有效的方法是我从其他答案和在线文档中获得的代码的混合。下面是哪些有效,哪些无效 问题: 是否有一种简单的方法可以从字节[,]数组开始,不使用GetPixel或Clone方法,将8bpp位图转换为1bpp,一次或一个字节一个字节?不安全代码是允许的 我的尝试(有
MWNumericArray
转换为黑白图片(而不是灰度)。起初,我尝试将2D字节数组转换为1D字节数组,然后将其复制到BitmapData对象并在位图中进行转换,但没有成功,因为我在尝试操作此数据时肯定犯了几个错误
有效的方法是我从其他答案和在线文档中获得的代码的混合。下面是哪些有效,哪些无效
问题:
是否有一种简单的方法可以从字节[,]
数组开始,不使用GetPixel
或Clone
方法,将8bpp位图转换为1bpp,一次或一个字节一个字节?不安全代码是允许的
我的尝试(有效):
// Most of this code is based on a Jon Skeet's answer.
// resultOut[0] is a 2D 356x356 MWArray
var numArray = (MWNumericArray)resultOut[0];
var data = numArray.ToArray(MWArrayComponent.Real) as byte[,];
var w = data.GetLength(0);
var h = data.GetLength(1);
unsafe
{
fixed (byte* ptr = data)
{
var scan0 = new IntPtr(ptr);
var bpm1 = new Bitmap(
w, h, // image size
w, // scan size
PixelFormat.Format8bppIndexed, scan0);
// works but is grayscale, not B&W
var palette = bpm1.Palette;
palette.Entries[0] = Color.Black;
for (var i = 1; i < 256; i++)
{
palette.Entries[i] = Color.FromArgb((i * 7) % 256, (i * 7) % 256, 255);
}
bpm1.Palette = palette;
bpm1.Save("output.grayscale.png");
// works but with additional helper method call
// based on a Hans Passant answer
var bpm2 = BitmapTo1Bpp(bpm1);
bpm2.Save("output.helper.png");
// works but uses Clone
var bpm3 = bpm1.Clone(new Rectangle(0, 0, bpm1.Width, bpm1.Height), PixelFormat.Format1bppIndexed);
bpm3.Save("output.clone.png");
}
}
if (numArray.ToArray(MWArrayComponent.Real) is byte[,] data)
{
// Convert to 1D byte array
var h = data.GetLength(1);
var w = data.GetLength(0);
var byteArray1D = new byte[h * w];
for (var i = 0; i < h; i++)
{
for (var j = 0; j < w; j++)
{
byteArray1D[i + j] = data[i, j];
}
}
// Create Bitmap object
var bmp = new Bitmap(w, h, PixelFormat.Format8bppIndexed);
//// Set palette
// var cp = bmp.Palette;
// for (var i = 0; i < 256; ++i)
// {
// cp.Entries[i] = Color.FromArgb(255, i, i, i);
// }
// bmp.Palette = cp;
var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.WriteOnly,
bmp.PixelFormat);
Marshal.Copy(byteArray1D,
0,
bmpData.Scan0,
byteArray1D.Length);
bmp.UnlockBits(bmpData);
// Does not work: graphic object cannot be created from an image that has an indexed pixel format
using (var g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
}
// Does not work: saves all black image
bmp.Save("output.raw.png");
using (var ms = new MemoryStream())
{
ms.Write(byteArray1D, 0, byteArray1D.Length);
ms.Seek(0, SeekOrigin.Begin); // ms.Position = 0;
// Does not work: parameter is not valid exception
var bm = new Bitmap(ms);
bm.Save("output.ms.png");
// Does not work: parameter is not valid exception
var newImage = Image.FromStream(ms);
newImage.Save("output.fromstream.png");
}
}
//此代码大部分基于Jon Skeet的答案。
//resultOut[0]是一个2D 356x356MWx阵列
var numArray=(MWNumericArray)结果为[0];
var data=numArray.ToArray(MWArrayComponent.Real)作为字节[,];
var w=数据。GetLength(0);
var h=data.GetLength(1);
不安全的
{
固定(字节*ptr=数据)
{
var scan0=新的IntPtr(ptr);
var bpm1=新位图(
w、 h,//图像大小
w、 //扫描大小
PixelFormat.Format8Bppined,扫描0);
//工作,但是灰度,而不是黑白
变量调色板=bpm1。调色板;
palete.Entries[0]=Color.Black;
对于(变量i=1;i<256;i++)
{
palete.Entries[i]=Color.FromArgb((i*7)%256,(i*7)%256255);
}
bpm1.调色板=调色板;
bpm1.Save(“output.grayscale.png”);
//可以工作,但需要额外的助手方法调用
//基于Hans Passant的回答
var bpm2=位映射到bpp(bpm1);
bpm2.Save(“output.helper.png”);
//工作,但使用克隆
var bpm3=bpm1.Clone(新矩形(0,0,bpm1.Width,bpm1.Height),PixelFormat.format1bpindexed);
bpm3.Save(“output.clone.png”);
}
}
我尝试的内容(无效):
// Most of this code is based on a Jon Skeet's answer.
// resultOut[0] is a 2D 356x356 MWArray
var numArray = (MWNumericArray)resultOut[0];
var data = numArray.ToArray(MWArrayComponent.Real) as byte[,];
var w = data.GetLength(0);
var h = data.GetLength(1);
unsafe
{
fixed (byte* ptr = data)
{
var scan0 = new IntPtr(ptr);
var bpm1 = new Bitmap(
w, h, // image size
w, // scan size
PixelFormat.Format8bppIndexed, scan0);
// works but is grayscale, not B&W
var palette = bpm1.Palette;
palette.Entries[0] = Color.Black;
for (var i = 1; i < 256; i++)
{
palette.Entries[i] = Color.FromArgb((i * 7) % 256, (i * 7) % 256, 255);
}
bpm1.Palette = palette;
bpm1.Save("output.grayscale.png");
// works but with additional helper method call
// based on a Hans Passant answer
var bpm2 = BitmapTo1Bpp(bpm1);
bpm2.Save("output.helper.png");
// works but uses Clone
var bpm3 = bpm1.Clone(new Rectangle(0, 0, bpm1.Width, bpm1.Height), PixelFormat.Format1bppIndexed);
bpm3.Save("output.clone.png");
}
}
if (numArray.ToArray(MWArrayComponent.Real) is byte[,] data)
{
// Convert to 1D byte array
var h = data.GetLength(1);
var w = data.GetLength(0);
var byteArray1D = new byte[h * w];
for (var i = 0; i < h; i++)
{
for (var j = 0; j < w; j++)
{
byteArray1D[i + j] = data[i, j];
}
}
// Create Bitmap object
var bmp = new Bitmap(w, h, PixelFormat.Format8bppIndexed);
//// Set palette
// var cp = bmp.Palette;
// for (var i = 0; i < 256; ++i)
// {
// cp.Entries[i] = Color.FromArgb(255, i, i, i);
// }
// bmp.Palette = cp;
var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.WriteOnly,
bmp.PixelFormat);
Marshal.Copy(byteArray1D,
0,
bmpData.Scan0,
byteArray1D.Length);
bmp.UnlockBits(bmpData);
// Does not work: graphic object cannot be created from an image that has an indexed pixel format
using (var g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
}
// Does not work: saves all black image
bmp.Save("output.raw.png");
using (var ms = new MemoryStream())
{
ms.Write(byteArray1D, 0, byteArray1D.Length);
ms.Seek(0, SeekOrigin.Begin); // ms.Position = 0;
// Does not work: parameter is not valid exception
var bm = new Bitmap(ms);
bm.Save("output.ms.png");
// Does not work: parameter is not valid exception
var newImage = Image.FromStream(ms);
newImage.Save("output.fromstream.png");
}
}
if(numArray.ToArray(MWArrayComponent.Real)是字节[,]数据)
{
//转换为1D字节数组
var h=data.GetLength(1);
var w=数据。GetLength(0);
var byteArray1D=新字节[h*w];
对于(变量i=0;i
在Matlab中转换为jpg比在c#中更有效。您可以从matlab返回字节[],然后使用c#中的BinaryWriter将其保存到文件中。@jdweng谢谢,不过这是一个我无法访问的库。独立于Matlab,问题是b&w位图中更多的字节[,],而不使用getpixel或clone,而是直接操作字节。字节[,]可能是与Matlab和c#中相同的位图。所以我应该说在matlab中处理位图更有效。