Files
2025-07-14 12:03:59 +02:00

131 lines
3.6 KiB
C#

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
namespace Inspectron.Camera.Image
{
public class ByteImage : IImage
{
Byte[] data;
int step;
/// <summary>
/// Initializes a newinstance with the given image dimensions and pixel-data
/// </summary>
/// <param name="width">the image width in pixel</param>
/// <param name="height">the image height in pixel</param>
/// <param name="channels">the number of color channels (1-4)</param>
/// <param name="channelDepth">the bit-depth per channel (8 or 16)</param>
/// <param name="data">pointer to the pixel data in unmanaged memory</param>
/// <param name="step">the number of bytes per image row</param>
public ByteImage(int width, int height, int channels,
Byte[] data, int step)
{
Width = width;
Height = height;
Channels = channels;
this.data = data;
this.step = step;
ProcessBitmapCache();
}
private void ProcessBitmapCache()
{
var image = new Bitmap(Width, Height,
Channels == 1 ? PixelFormat.Format8bppIndexed : PixelFormat.Format24bppRgb);
var lockedDst = image.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly,
image.PixelFormat);
Marshal.Copy(data, 0, lockedDst.Scan0, data.Length);
image.UnlockBits(lockedDst);
if (Channels == 1)
{
image.Palette = _monoPalette;
}
_cachedBMP = image;
}
static ColorPalette GetGrayScalePalette()
{
Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed);
ColorPalette monoPalette = bmp.Palette;
Color[] entries = monoPalette.Entries;
for (int i = 0; i < 256; i++)
{
entries[i] = Color.FromArgb(i, i, i);
}
return monoPalette;
}
private static ColorPalette _monoPalette = GetGrayScalePalette();
public int Width { get; private set; }
public int Height { get; private set; }
public int Channels { get; private set; }
public IImageLock Lock { get { return new ImageLock(this); } }
private Bitmap _cachedBMP = null;
public Bitmap Bitmap
{
get
{
return (Bitmap)_cachedBMP.Clone();
}
}
public byte[] Data
{
get => data;
set => data = value;
}
public int Step
{
get => step;
set => step = value;
}
class ImageLock : IImageLock
{
ByteImage parent;
GCHandle pinnedArray;
internal ImageLock(ByteImage parent) { this.parent = parent; }
public int Step { get { return parent.step; } }
public IntPtr PixelData
{
get
{
pinnedArray = GCHandle.Alloc(parent.data, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
return pointer;
}
}
public void Dispose()
{
pinnedArray.Free();
}
}
public void Save(string path)
{
(new Bitmap(new MemoryStream(data))).Save(path,ImageFormat.Bmp);
}
public void Dispose()
{
data = null;
}
}
}