基于winfrom平台 使用了button和pictureBox和comboBox等控件完成 代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Diagnostics;
using System.IO;
namespace 转换程序
{
public partial class Form1 : Form
{
Bitmap curBitmap;
public static int g = 0;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog op = new OpenFileDialog();
if (op.ShowDialog() == DialogResult.OK)
{
curBitmap = (Bitmap)Bitmap.FromFile(op.FileName);
pictureBox1.Image = curBitmap;
}
}
private void button2_Click(object sender, EventArgs e)
{
g++;
switch (comboBox1.Text)
{
case "8bit":
if (curBitmap != null)
{
pictureBox1.Image = transForm24to8(curBitmap);
}
break;
case "24bit":
if (curBitmap != null)
{
pictureBox1.Image = transForm8to24(curBitmap);
}
break;
}
}
/// <summary>
/// 24bit转8bit
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static Bitmap transForm24to8(Bitmap bmp)
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmpData.Stride * bmpData.Height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
Rectangle rect2 = new Rectangle(0, 0, bmp.Width, bmp.Height);
Bitmap bit = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format8bppIndexed);
System.Drawing.Imaging.BitmapData bmpData2 = bit.LockBits(rect2, System.Drawing.Imaging.ImageLockMode.ReadWrite, bit.PixelFormat);
IntPtr ptr2 = bmpData2.Scan0;
int bytes2 = bmpData2.Stride * bmpData2.Height;
byte[] rgbValues2 = new byte[bytes2];
System.Runtime.InteropServices.Marshal.Copy(ptr2, rgbValues2, 0, bytes2);
double colorTemp = 0;
for (int i = 0; i < bmpData.Height; i++)
{
for (int j = 0; j < bmpData.Width * 3; j += 3)
{
colorTemp = rgbValues[i * bmpData.Stride + j + 2] * 0.299 + rgbValues[i * bmpData.Stride + j + 1] * 0.578 + rgbValues[i * bmpData.Stride + j] * 0.114;
rgbValues2[i * bmpData2.Stride + j / 3] = (byte)colorTemp;
}
}
System.Runtime.InteropServices.Marshal.Copy(rgbValues2, 0, ptr2, bytes2);
bmp.UnlockBits(bmpData);
ColorPalette tempPalette;
{
using (Bitmap tempBmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
{
tempPalette = tempBmp.Palette;
}
for (int i = 0; i < 256; i++)
{
tempPalette.Entries[i] = Color.FromArgb(i, i, i);
}
bit.Palette = tempPalette;
}
bit.UnlockBits(bmpData2);
string path = ((g++).ToString())+"_8bit" + ".bmp";
bit.Save(@"F:/图片/"+path);
return bit;
}
/// <summary>
/// 8位转24位
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static Bitmap transForm8to24(Bitmap bmp)
{
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bitmapData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
//计算实际8位图容量
int size8 = bitmapData.Stride * bmp.Height;
byte[] grayValues = new byte[size8];
//// 申请目标位图的变量,并将其内存区域锁定
Bitmap TempBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format24bppRgb);
BitmapData TempBmpData = TempBmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
//// 获取图像参数以及设置24位图信息
int stride = TempBmpData.Stride; // 扫描线的宽度
int offset = stride - TempBmp.Width; // 显示宽度与扫描线宽度的间隙
IntPtr iptr = TempBmpData.Scan0; // 获取bmpData的内存起始位置
int scanBytes = stride * TempBmp.Height;// 用stride宽度,表示这是内存区域的大小
//// 下面把原始的显示大小字节数组转换为内存中实际存放的字节数组
byte[] pixelValues = new byte[scanBytes]; //为目标数组分配内存
System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, grayValues, 0, size8);
for (int i = 0; i < bmp.Height; i++)
{
for (int j = 0; j < bitmapData.Stride; j++)
{
if (j >= bmp.Width)
continue;
int indexSrc = i * bitmapData.Stride + j;
int realIndex = i * TempBmpData.Stride + j * 3;
pixelValues[realIndex] = grayValues[indexSrc];
pixelValues[realIndex + 1] = grayValues[indexSrc];
pixelValues[realIndex + 2] = grayValues[indexSrc];
}
}
//// 用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, iptr, scanBytes);
TempBmp.UnlockBits(TempBmpData); // 解锁内存区域
bmp.UnlockBits(bitmapData);
string path = (g++).ToString() +"_24bit"+ ".bmp";
TempBmp.Save(@"F:/图片/"+path);
return TempBmp;
}
}
}