我需要写一个文件(BMP格式)。该程序应:•加载并在屏幕上显示任意文件(使用文件功能);
•检查有效的文件格式;
•最多读取256种颜色(黑白,灰色,16,256种);
•显示来自文件标题的信息(类型,大小,分辨率,压缩的使用,颜色数量,...)以及调色板;
•提供滚动图像。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace Project1
{
public partial class Form1: Form
{
[DllImport ("winmm.dll")]
private static extern long mciSendString (string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);
private string sCommand = "";
public int k;
public string path;
public Color [] pixel;
public Form1 ()
{
this.components = ((IContainer) null);
this.path = "";
this.k = 0;
this.InitializeComponent ();
error = new error ();
Zooom = new Zooom ();
}
// error error;
// Zooom Zooom;
private void openToolStripMenuItem_Click (object sender, EventArgs e)
{
this.label1.Visible = false;
this.label2.Visible = false;
this.label3.Visible = false;
this.label4.Visible = false;
this.label5.Visible = false;
this.label7.Visible = false;
this.label8.Visible = false;
this.listView2.Visible = false;
this.pictureBox1.Image = null;
OpenFileDialog dialog = new OpenFileDialog ();
if (dialog.ShowDialog () == DialogResult.OK)
{
this.path = dialog.FileName;
FileStream stream = new FileStream (this.path, FileMode.Open, FileAccess.Read); // synchronous and asynchronous write and read
byte [] buffer = new byte [Marshal.SizeOf (typeof (BITMAPFILEHEADER))]; // memory allocation for unmanaged code
stream.Read (buffer, 0, Marshal.SizeOf (typeof (BITMAPFILEHEADER))); // read bytes from the stream and write data to the specified buffer
GCHandle handle = GCHandle.Alloc (buffer, GCHandleType.Pinned); // access to a managed object from unmanaged memory
BITMAPFILEHEADER bitmapfileheader = (BITMAPFILEHEADER) Marshal.PtrToStructure (handle.AddrOfPinnedObject (), typeof (BITMAPFILEHEADER)); // transfer from unmanaged to managed memory
handle.Free ();
if (bitmapfileheader.bfType == 0x4d42)
{
this.k ++;
}
else
{
sCommand = "open \" "+ @" D: \ 1.mp3 "+" \ "type mpegvideo alias MediaFile";
// send a command
mciSendString (sCommand, null, 0, IntPtr.Zero);
// command to play the file
sCommand = "play MediaFile";
// send a command
mciSendString (sCommand, null, 0, IntPtr.Zero);
error.ShowDialog ();
}
}
}
private void viewToolStripMenuItem_Click (object sender, EventArgs e)
{
if (this.k <= 0)
{
this.pictureBox1.Image = null;
}
else
{
int num8;
int num9;
int num10;
int num11;
this.label1.Visible = false;
this.label2.Visible = false;
this.label3.Visible = false;
this.label4.Visible = false;
this.label5.Visible = false;
this.label7.Visible = false;
this.label8.Visible = false;
this.listView1.Visible = false;
this.AutoScroll = false;
char [,] chArray = new char [256, 4]; // 256
char [] chArray2 = new char [1024]; // 1024
FileStream stream = new FileStream (this.path, FileMode.Open, FileAccess.Read);
byte [] buffer1 = new byte [Marshal.SizeOf (typeof (BITMAPFILEHEADER))];
stream.Read (buffer1, 0, Marshal.SizeOf (typeof (BITMAPFILEHEADER)));
GCHandle handle = GCHandle.Alloc (buffer1, GCHandleType.Pinned);
BITMAPFILEHEADER bitmapfileheader = (BITMAPFILEHEADER) Marshal.PtrToStructure (handle.AddrOfPinnedObject (), typeof (BITMAPFILEHEADER));
handle.Free ();
int biBitCount = bitmapfileheader.biBitCount;
this.AutoScroll = true;
this.pictureBox1.Image = null;
int x = 0;
int y = 0;
int index = 0;
Color [] colorArray = new Color [256]; // 256
int biWidth = bitmapfileheader.biWidth;
int biHeight = bitmapfileheader.biHeight;
int num7 = bitmapfileheader.biWidth + (((bitmapfileheader.biWidth% 4) == 0)? 0: (4 - (bitmapfileheader.biWidth% 4)));
Bitmap bitmap = new Bitmap (biWidth +2, biHeight + 2);
switch (bitmapfileheader.biBitCount)
{
case 1:
{
index = 0;
while (index <(((int) 1) << bitmapfileheader.biBitCount))
{
num8 = stream.ReadByte ();
num9 = stream.ReadByte ();
num10 = stream.ReadByte ();
num11 = stream.ReadByte ();
colorArray [index] = Color.FromArgb (255, num10, num9, num8);
index ++;
}
index = 0;
x = 0;
y = biHeight;
int ReadInString = 0; // read bits in string
int ReadGroupByte = 0; // read bytes in a group of 4
for (index = 0; stream.Position <stream.Length; index + = 1)
{
ReadGroupByte ++;
if (ReadGroupByte == 4)
ReadGroupByte = 0;
if (ReadInString == biWidth)
{
ReadInString = 0;
x = 0; y--;
if (y <0)
break;
index + = 4 - ReadGroupByte;
ReadGroupByte = 0;
continue;
}
else // not all bits have been read in the string yet.
{
num11 = stream.ReadByte ();
for (int j = 0; j <8; j ++)
{
if (ReadInString == biWidth)
{
x = 0; y--;
break;}
int indexBit = ((num11 >> (7 - j)) & 1);
ReadInString ++;
bitmap.SetPixel (x, y, colorArray [indexBit]);
x ++;
}
}
}
break;
}
case 2:
index = 0;
while (index <(((int) 1) << bitmapfileheader.biBitCount))
{
num8 = stream.ReadByte ();
num9 = stream.ReadByte ();
num10 = stream.ReadByte ();
num11 = stream.ReadByte ();
colorArray [index] = Color.FromArgb (0xff, num10, num9, num8);
index ++;
}
for (index = 0; stream.Position <stream.Length; index ++)
{
x = index% num7; // assignment of balance
y = biHeight - (index / num7);
num11 = stream.ReadByte ();
x = index% num7;
y = biHeight - (index / num7);
bitmap.SetPixel (x, y, colorArray [num11]);
}
break;
case 4:
index = 0;
while (index <(((int) 1) << bitmapfileheader.biBitCount))
{
num8 = stream.ReadByte ();
num9 = stream.ReadByte ();
num10 = stream.ReadByte ();
num11 = stream.ReadByte ();
colorArray [index] = Color.FromArgb (0xff, num10, num9, num8);
index ++;
}
index = 0;
while (stream.Position <stream.Length)
{
num11 = stream.ReadByte ();
x = index% num7;
y = biHeight - (index / num7);
bitmap.SetPixel (x, y, colorArray [num11 >> 4]);
bitmap.SetPixel (x + 1, y, colorArray [num11 & 15]);
index + = 2;
}
break;
case 8:
for (index = 0; index <(((int) 1) << bitmapfileheader.biBitCount); index ++)
{
num8 = stream.ReadByte ();
num9 = stream.ReadByte ();
num10 = stream.ReadByte ();
num11 = stream.ReadByte ();
colorArray [index] = Color.FromArgb (0xff, num10, num9, num8); // 0xff - 255
}
index = 0;
while (stream.Position <stream.Length)
{
num11 = stream.ReadByte ();
x = index% num7;
y = biHeight - (index / num7);
bitmap.SetPixel (x, y, colorArray [num11]);
index ++;
}
break;
case 24:
while (stream.Position <stream.Length)
{
num8 = stream.ReadByte ();
num9 = stream.ReadByte ();
num10 = stream.ReadByte ();
x = index% num7;
y = biHeight - (index / num7);
bitmap.SetPixel (x, y, Color.FromArgb (0xff, num10, num9, num8));
index ++;
}
break;
}
this.pictureBox1.Width = bitmapfileheader.biWidth;
this.pictureBox1.Height = bitmapfileheader.biHeight;
this.pictureBox1.Image = bitmap;
bitmap.Save ("1.bmp");
}
}
private void pictureBox1_Click (object sender, EventArgs e)
{
}
private void infoToolStripMenuItem_Click (object sender, EventArgs e)
{
if (this.k <= 0)
{
this.label1.Visible = false;
this.label2.Visible = false;
this.label3.Visible = false;
this.label4.Visible = false;
this.label5.Visible = false;
this.label7.Visible = false;
this.label8.Visible = false;
this.listView2.Visible = false;
this.AutoScroll = false;
}
else
{
this.label1.Visible = true;
this.label2.Visible = true;
this.label3.Visible = true;
this.label4.Visible = true;
this.label5.Visible = true;
this.label7.Visible = true;
this.label8.Visible = true;
this.listView2.Visible = false;
this.AutoScroll = true;
this.pictureBox1.Image = null;
string [] strArray = new string [10];
FileStream stream = new FileStream (this.path, FileMode.Open, FileAccess.Read);
byte [] buffer = new byte [Marshal.SizeOf (typeof (BITMAPFILEHEADER))];
stream.Read (buffer, 0, Marshal.SizeOf (typeof (BITMAPFILEHEADER)));
GCHandle handle = GCHandle.Alloc (buffer, GCHandleType.Pinned);
BITMAPFILEHEADER bitmapfileheader = (BITMAPFILEHEADER) Marshal.PtrToStructure (handle.AddrOfPinnedObject (), typeof (BITMAPFILEHEADER));
handle.Free ();
if (bitmapfileheader.bfType == 19778)
{
this.label8.Text = "Path and filename:" + stream.Name;
this.label1.Text = "File Type: BMP";
this.label2.Text = "File size:" + bitmapfileheader.bfSize.ToString () + "(byte)";
this.label3.Text = "Image height:" + bitmapfileheader.biHeight.ToString ();
this.label4.Text = "Image width:" + bitmapfileheader.biWidth.ToString ();
switch (bitmapfileheader.biBitCount)
{
case 1:
this.label5.Text = "Number of colors: 2";
break;
case 24:
this.label5.Text = "Number of colors: the palette is not used, each three byte of the image represents one pixel, byte for the intensity of the blue, green and red channels, respectively";
break;
case 32:
if (bitmapfileheader.biCompression == 0)
{
this.label5.Text = "Number of colors: the image does not contain a palette";
}
else
{
this.label5.Text = "Number of colors: Every four bytes of the image represent one pixel, byte for the intensity of the blue, green and red channels, respectively";
}
break;
case 8:
this.label5.Text = "Number of colors: The palette contains up to 256 colors, each byte of the image stores an index in the palette for one pixel";
break;
case 16:
if (bitmapfileheader.biCompression == 0)
{
this.label5.Text = "Number of colors: the image does not contain a palette";
}
else
{
this.label5.Text = "Number of colors: Every two bytes of the image store the intensity of the red, green and blue components of one pixel";
}
break;
}
switch (bitmapfileheader.biCompression)
{
case 0:
this.label7.Text = "Compression Type: Uncompressed Image";
break;
case 1:
this.label7.Text = "Compression type: RLE compression for 8-bit images";
break;
case 2:
this.label7.Text = "Compression type: RLE compression for 4-bit images";
break;
case 4:
this.label7.Text = "Compression Type: Win98 / Me / 2000 / XP: JPEG Compression";
break;
case 5:
this.label7.Text = "Compression Type: Win98 / Me / 2000 / XP: PNG Compression";
break;
case 6:
this.label7.Text = "Compression type: WinCE: the image is not compressed, the palette contains four 4-byte masks for the red, green, blue and transparent (alpha channel) color component. Used for 16-bit and 32-bit images";
break;
}
}
}
}
private void colorToolStripMenuItem_Click (object sender, EventArgs e)
{
if (this.k> 0)
{
int num2;
int num3;
int num4;
int num5;
this.label1.Visible = false;
this.label2.Visible = false;
this.label3.Visible = false;
this.label4.Visible = false;
this.label5.Visible = false;
this.label7.Visible = false;
this.label8.Visible = false;
this.pictureBox1.Visible = false;
this.listView2.Visible = true;
this.listView2.Clear ();
string [] strArray = new string [10];
FileStream stream = new FileStream (this.path, FileMode.Open, FileAccess.Read);
byte [] buffer = new byte [Marshal.SizeOf (typeof (BITMAPFILEHEADER))];
stream.Read (buffer, 0, Marshal.SizeOf (typeof (BITMAPFILEHEADER)));
GCHandle handle = GCHandle.Alloc (buffer, GCHandleType.Pinned);
BITMAPFILEHEADER bitmapfileheader = (BITMAPFILEHEADER) Marshal.PtrToStructure (handle.AddrOfPinnedObject (), typeof (BITMAPFILEHEADER));
handle.Free ();
int num = 0;
int num6 = 0;
switch (bitmapfileheader.biBitCount)
{
case 4:
while (stream.Position <1078)
{
num2 = stream.ReadByte ();
num3 = stream.ReadByte ();
num4 = stream.ReadByte ();
num5 = stream.ReadByte ();
this.listView2.Items.Add (Convert.ToString (num6));
this.listView2.Items [num6] .BackColor = Color.FromArgb (num5, num4, num3, num2);
num6 ++;
num ++;
}
break;
case 8:
{
while (stream.Position <1078)
{
num2 = stream.ReadByte ();
num3 = stream.ReadByte ();
num4 = stream.ReadByte ();
num5 = stream.ReadByte ();
this.listView2.Items.Add (Convert.ToString (num6));
this.listView2.Items [num6] .BackColor = Color.FromArgb (num5, num4, num3, num2);
num6 ++;
num ++;
}
break;
}
case 24:
MessageBox.Show ("No Palette!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
break;
}
}
}
private void label8_Click (object sender, EventArgs e)
{
}
private void zoomToolStripMenuItem_Click (object sender, EventArgs e)
{
Zooom.Show ();
}
private void Form1_Load (object sender, EventArgs e)
{
}
}
}
答案 0 :(得分:0)
我看到你正在做一个互操作。 BITMAPFILEHEADER不是C#结构,而是C ++,您必须在C#中创建一个才能使用
[StructLayout(LayoutKind.Sequential, Pack=2)]
public struct BITMAPFILEHEADER
{
public ushort bfType;
public uint bfSize;
public ushort bfReserved1;
public ushort bfReserved2;
public uint bfOffBits;
}
您应该查看pinvoke.net和MSDN文档以获取更多信息 https://www.pinvoke.net/default.aspx/Structures.BITMAPFILEHEADER
https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/ns-wingdi-tagbitmapfileheader
我建议您看一下C#中的System.Drawing.Bitmap类。这些使用GDI。