SGI图形前2个字节 0x01,0xDA 应该是文件标识
第7个字节和第8个字节 是图形的宽
第9和第10个字节 是图形的高
一直到512个字节才是图形数据..这里的图形数据格式和PCX文件一样 先是文件RED分量 然后个Green 最后才是Blue ..
也就是说 先读取所有的RED分量然后Green.
使用方法
RED分量
ImageSGI _SGI = new ImageSGI(@"c:\tEMP\24.SGI");
pictureBox1.Image = _SGI.Image;
_SGI.Image = this.Icon.ToBitmap();
_SGI.SaveImage(@"C:\111.SGI");
下面是全部代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace WindowsApplication1
{
/// <summary>
/// Targa文件
/// </summary>
public class ImageSGI
{
public ImageSGI()
{
}
public ImageSGI(string p_FileFullName)
{
if (System.IO.File.Exists(p_FileFullName))
{
LoadData(File.ReadAllBytes(p_FileFullName));
}
}
#region 属性
/// <summary>
/// 文件头
/// </summary>
private byte[] m_Header = new byte[] { 0x01, 0xDA, 0x0, 0x1, 0x0, 0x3 };
/// <summary>
/// 宽
/// </summary>
private ushort m_Width = 0;
/// <summary>
/// 高
/// </summary>
private ushort m_Height = 0;
/// <summary>
/// 未知数据
/// </summary>
private byte[] m_UnknownData1 = new byte[] { 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF };
/// <summary>
/// 未知数据
/// </summary>
private byte[] m_UnknownData2 = new byte[492];
/// <summary>
/// 图形
/// </summary>
private Bitmap m_Image;
#endregion
/// <summary>
/// 图形
/// </summary>
public Bitmap Image
{
get { return m_Image; }
set
{
if (value != null)
{
m_Width = (ushort)value.Width;
m_Height = (ushort)value.Height;
if (value.PixelFormat != PixelFormat.Format24bppRgb)
{
Bitmap _NewBitmap = new Bitmap(value.Width, value.Height, PixelFormat.Format24bppRgb);
Graphics _Graphics = Graphics.FromImage(_NewBitmap);
_Graphics.DrawImage(value, new Rectangle(0, 0, value.Width, value.Height));
_Graphics.Dispose();
m_Image = _NewBitmap;
return;
}
}
m_Image = value;
}
}
/// <summary>
/// 获取数据
/// </summary>
/// <param name="p_TGABytes"></param>
private void LoadData(byte[] p_SGIBytes)
{
if (p_SGIBytes[0] == m_Header[0] && p_SGIBytes[1] == m_Header[1] && p_SGIBytes[2] == m_Header[2] && p_SGIBytes[3] == m_Header[3] && p_SGIBytes[4] == m_Header[4] && p_SGIBytes[5] == m_Header[5])
{
byte[] _ValueInt16 = new byte[2];
_ValueInt16[1] = p_SGIBytes[6];
_ValueInt16[0] = p_SGIBytes[7];
m_Width = BitConverter.ToUInt16(_ValueInt16, 0);
_ValueInt16[1] = p_SGIBytes[8];
_ValueInt16[0] = p_SGIBytes[9];
m_Height = BitConverter.ToUInt16(_ValueInt16, 0);
int _ReadIndex = 512;
LoadImageData(p_SGIBytes, ref _ReadIndex);
}
else
{
throw new Exception("格式不正确!");
}
}
/// <summary>
/// 获取数据到图形
/// </summary>
/// <param name="p_TAGBytes">数据</param>
/// <param name="p_ReadIndex">数据开始位置</param>
private void LoadImageData(byte[] p_SGIBytes,ref int p_ReadIndex)
{
m_Image = new Bitmap(m_Width, m_Height, PixelFormat.Format24bppRgb);
BitmapData _ImageData = m_Image.LockBits(new Rectangle(0, 0, m_Image.Width, m_Image.Height), ImageLockMode.ReadWrite, m_Image.PixelFormat);
byte[] _WriteBytes = new byte[_ImageData.Stride * _ImageData.Height];
int _WriteIndex = 0;
int _Address = m_Width * m_Height;
for (int i = _ImageData.Height-1; i != -1; i--)
{
_WriteIndex = i * _ImageData.Stride;
for (int z = 0; z != _ImageData.Width; z++)
{
_WriteBytes[_WriteIndex + 2] = p_SGIBytes[p_ReadIndex];
_WriteBytes[_WriteIndex + 1] = p_SGIBytes[p_ReadIndex + _Address];
_WriteBytes[_WriteIndex] = p_SGIBytes[p_ReadIndex + _Address * 2];
_WriteIndex += 3;
p_ReadIndex++;
}
}
Marshal.Copy(_WriteBytes, 0, _ImageData.Scan0, _WriteBytes.Length);
m_Image.UnlockBits(_ImageData);
}
/// <summary>
/// 保存SGI图形到文件
/// </summary>
/// <param name="p_FileFullName"></param>
public void SaveImage(string p_FileFullName)
{
if (m_Image != null) File.WriteAllBytes(p_FileFullName, SaveImageToSGI());
}
private byte[] SaveImageToSGI()
{
BitmapData _ImageData = m_Image.LockBits(new Rectangle(0, 0, m_Image.Width, m_Image.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte[] _WriteBytes = new byte[_ImageData.Stride * _ImageData.Height];
Marshal.Copy(_ImageData.Scan0, _WriteBytes, 0, _WriteBytes.Length);
m_Image.UnlockBits(_ImageData);
int _ReadIndex = 0;
int _WidthIndex = 0;
int _Address = m_Width * m_Height;
byte[] _Red = new byte[_Address];
byte[] _Green = new byte[_Address];
byte[] _Blue = new byte[_Address];
for (int i = _ImageData.Height - 1; i != -1; i--)
{
_ReadIndex = i * _ImageData.Stride;
for (int z = 0; z != _ImageData.Width; z++)
{
_Red[_WidthIndex] = _WriteBytes[_ReadIndex + 2];
_Green[_WidthIndex] = _WriteBytes[_ReadIndex + 1];
_Blue[_WidthIndex] = _WriteBytes[_ReadIndex];
_ReadIndex += 3;
_WidthIndex++;
}
}
MemoryStream _Stream = new MemoryStream();
_Stream.Write(m_Header, 0, m_Header.Length);
byte[] _ValueInt16 = BitConverter.GetBytes(m_Width);
Array.Reverse(_ValueInt16);
_Stream.Write(_ValueInt16, 0,2);
_ValueInt16 = BitConverter.GetBytes(m_Height);
Array.Reverse(_ValueInt16);
_Stream.Write(_ValueInt16, 0, 2);
_Stream.Write(m_UnknownData1, 0, m_UnknownData1.Length);
_Stream.Write(m_UnknownData2, 0, m_UnknownData2.Length);
_Stream.Write(_Red, 0, _Address);
_Stream.Write(_Green, 0, _Address);
_Stream.Write(_Blue, 0, _Address);
return _Stream.ToArray();
}
}
}