1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Media;
using System.Windows;
using DirectShowLib;
using System.Windows.Interop;
using System.IO;
namespace Tango.Video.DirectShow
{
#region MakeBitmapSource
public class BitmapHelper
{
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
internal static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length);
public static WriteableBitmap FromNativePointer(IntPtr pData, long dataLength, int w, int h, int ch, bool flipImage)
{
PixelFormat format = PixelFormats.Default;
int bitCount = 8;
if (ch == 1) format = PixelFormats.Gray8; //grey scale image 0-255
if (ch == 3)
{
format = PixelFormats.Bgr24; //RGB
bitCount = 24;
}
if (ch == 4)
{
format = PixelFormats.Bgr32; //RGB + alpha
bitCount = 32;
}
WriteableBitmap wbm = new WriteableBitmap(w, h, 96, 96, format, null);
if (flipImage)
{
int stride = ((w * bitCount / 8) + 3) & ~3;
unsafe
{
var pDest = (byte*)wbm.BackBuffer;
var pSrc = (byte*)pData;
pSrc += dataLength;
for (int i = 0; i < h; i++)
{
byte* pDstTmp = pDest + i * stride;
byte* pSrcTemp = pSrc - (i + 1) * stride;
CopyMemory((IntPtr)pDstTmp, (IntPtr)pSrcTemp, (uint)stride);
}
}
}
else
{
CopyMemory(wbm.BackBuffer, pData, (uint)(w * h * ch));
}
wbm.Lock();
wbm.AddDirtyRect(new Int32Rect(0, 0, wbm.PixelWidth, wbm.PixelHeight));
wbm.Unlock();
return wbm;
}
public static BitmapSource FromArray(byte[] data, int w, int h, int ch)
{
PixelFormat format = PixelFormats.Default;
if (ch == 1) format = PixelFormats.Gray8; //grey scale image 0-255
if (ch == 3) format = PixelFormats.Bgr24; //RGB
if (ch == 4) format = PixelFormats.Bgr32; //RGB + alpha
WriteableBitmap wbm = new WriteableBitmap(w, h, 96, 96, format, null);
wbm.WritePixels(new Int32Rect(0, 0, w, h), data, ch * w, 0);
return wbm;
}
public static BitmapSource CreateEmptySource(System.Windows.Size size, System.Windows.Media.Color color)
{
int width = (int)size.Width;
int height = (int)size.Height;
int stride = width / 8;
byte[] pixels = new byte[height * stride];
try
{
return BitmapSource.Create(width, height, 96, 96, PixelFormats.Indexed1, new BitmapPalette(new List<System.Windows.Media.Color> { color }), pixels, stride);
}
catch
{
width = 1920;
height = 1080;
stride = width / 8;
pixels = new byte[height * stride];
return BitmapSource.Create(width, height, 96, 96, PixelFormats.Indexed1, new BitmapPalette(new List<System.Windows.Media.Color> { color }), pixels, stride);
}
}
public static WriteableBitmap BitmapSourceToWriteableBitmap(BitmapSource source)
{
int stride = source.PixelWidth * (source.Format.BitsPerPixel / 8);
// Create data array to hold source pixel data
byte[] data = new byte[stride * source.PixelHeight];
// Copy source image pixels to the data array
source.CopyPixels(data, stride, 0);
// Create WriteableBitmap to copy the pixel data to.
WriteableBitmap target = new WriteableBitmap(
source.PixelWidth,
source.PixelHeight,
source.DpiX, source.DpiY,
source.Format, null);
// Write the pixel data to the WriteableBitmap.
target.WritePixels(
new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight),
data, stride, 0);
return target;
}
}
#endregion
}
|