Skip to content

Commit d63722d

Browse files
render methods for WinForms & WPF
1 parent c81262d commit d63722d

File tree

4 files changed

+117
-8
lines changed

4 files changed

+117
-8
lines changed

PPMLib/PPMLib.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
<Prefer32Bit>false</Prefer32Bit>
3535
</PropertyGroup>
3636
<ItemGroup>
37+
<Reference Include="PresentationCore" />
3738
<Reference Include="System" />
3839
<Reference Include="System.Core" />
3940
<Reference Include="System.Drawing" />
@@ -59,11 +60,12 @@
5960
<Compile Include="PPMFilename.cs" />
6061
<Compile Include="PPMFrame.cs" />
6162
<Compile Include="PPMLayer.cs" />
62-
<Compile Include="PPMRenderer.cs" />
6363
<Compile Include="PPMThumbnail.cs" />
6464
<Compile Include="PPMTimestamp.cs" />
6565
<Compile Include="Properties\AssemblyInfo.cs" />
6666
<Compile Include="Extensions\WavePcmFormat.cs" />
67+
<Compile Include="Winforms\PPMRenderer.cs" />
68+
<Compile Include="WPF\PPMRenderer.cs" />
6769
</ItemGroup>
6870
<ItemGroup>
6971
<Folder Include="Converters\" />

PPMLib/WPF/PPMRenderer.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Windows.Media;
4+
using System.Windows.Media.Imaging;
5+
6+
namespace PPMLib.WPF
7+
{
8+
public static class PPMRenderer
9+
{
10+
public static readonly List<Color> ThumbnailPalette = new List<Color>
11+
{
12+
Color.FromRgb(0xFF,0xFF,0xFF), Color.FromRgb(0x52,0x52,0x52), Color.FromRgb(0xFF,0xFF,0xFF), Color.FromRgb(0x9C,0x9C,0x9C),
13+
Color.FromRgb(0xFF,0x48,0x44), Color.FromRgb(0xC8,0x51,0x4F), Color.FromRgb(0xFF,0xAD,0xAC), Color.FromRgb(0x00,0xFF,0x00),
14+
Color.FromRgb(0x48,0x40,0xFF), Color.FromRgb(0x51,0x4F,0xB8), Color.FromRgb(0xAD,0xAB,0xFF), Color.FromRgb(0x00,0xFF,0x00),
15+
Color.FromRgb(0xB6,0x57,0xB7), Color.FromRgb(0x00,0xFF,0x00), Color.FromRgb(0x00,0xFF,0x00), Color.FromRgb(0x00,0xFF,0x00)
16+
};
17+
public static WriteableBitmap GetThumbnailBitmap(byte[] buffer)
18+
{
19+
if (buffer.Length != 1536)
20+
{
21+
throw new ArgumentException("Wrong thumbnail buffer size");
22+
}
23+
24+
byte[] bytes = new byte[32 * 48];
25+
26+
int offset = 0;
27+
for (int ty = 0; ty < 48; ty += 8)
28+
{
29+
for (int tx = 0; tx < 32; tx += 4)
30+
{
31+
for (int l = 0; l < 8; l++)
32+
{
33+
int line = (ty + l) << 5;
34+
for (int px = 0; px < 4; px++)
35+
{
36+
// Need to reverse nibbles :
37+
bytes[line + tx + px] = (byte)(((buffer[offset] & 0xF) << 4) | ((buffer[offset] & 0xF0) >> 4));
38+
offset += 1;
39+
}
40+
}
41+
}
42+
}
43+
44+
var palette = new BitmapPalette(ThumbnailPalette);
45+
// Directly set bitmap's 4-bit palette instead of using 32-bit colors
46+
var bmp = new WriteableBitmap(64, 48, 96, 96, PixelFormats.Indexed4, palette);
47+
bmp.WritePixels(new System.Windows.Int32Rect(0, 0, 64, 48), bytes, 32, 0);
48+
return bmp;
49+
}
50+
51+
public static readonly List<Color> FramePalette = new List<Color>
52+
{
53+
Color.FromRgb(0x00,0x00,0x00), Color.FromRgb(0xFF,0xFF,0xFF), Color.FromRgb(0xFF,0x00,0x00), Color.FromRgb(0x00,0x00,0xFF)
54+
};
55+
56+
private static Color GetLayerColor(PenColor pc,PaperColor paper)
57+
{
58+
if (pc == PenColor.Inverted) return FramePalette[1 - (int)paper];
59+
return FramePalette[(int)pc];
60+
}
61+
62+
public static WriteableBitmap GetFrameBitmap(PPMFrame frame)
63+
{
64+
var palette = new BitmapPalette(new List<Color>
65+
{
66+
FramePalette[(int)frame.PaperColor],
67+
GetLayerColor(frame.Layer1.PenColor,frame.PaperColor),
68+
GetLayerColor(frame.Layer2.PenColor,frame.PaperColor),
69+
});
70+
var bmp = new WriteableBitmap(256, 192, 96, 96, PixelFormats.Indexed2, palette);
71+
72+
int stride = 64;
73+
byte[] pixels = new byte[64 * 192];
74+
for (int x = 0; x < 256; x++)
75+
{
76+
for (int y = 0; y < 192; y++)
77+
{
78+
if (frame.Layer1[y, x])
79+
{
80+
int b = 256 * y + x;
81+
int p = 3 - b % 4;
82+
b /= 4;
83+
pixels[b] &= (byte)(~(0b11 << (2 * p)));
84+
pixels[b] |= (byte)(0b10 << (2 * p));
85+
}
86+
}
87+
}
88+
for (int x = 0; x < 256; x++)
89+
{
90+
for (int y = 0; y < 192; y++)
91+
{
92+
if (frame.Layer2[y, x])
93+
{
94+
int b = 256 * y + x;
95+
int p = 3 - b % 4;
96+
b /= 4;
97+
pixels[b] &= (byte)(~(0b11 << (2 * p)));
98+
pixels[b] |= (byte)(0b01 << (2 * p));
99+
}
100+
}
101+
}
102+
bmp.WritePixels(new System.Windows.Int32Rect(0, 0, 256, 192), pixels, stride, 0);
103+
return bmp;
104+
}
105+
106+
}
107+
}

PPMLib/PPMRenderer.cs renamed to PPMLib/Winforms/PPMRenderer.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
using System.Drawing.Imaging;
66
using System.Runtime.InteropServices;
77

8-
namespace PPMLib
8+
namespace PPMLib.Winforms
99
{
1010
public static class PPMRenderer
1111
{
@@ -72,12 +72,12 @@ public static Bitmap GetFrameBitmap(PPMFrame frame)
7272
var rect = new Rectangle(0, 0, 256, 192);
7373
var bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
7474

75-
byte[] bytes = new byte[256 * 192];
75+
byte[] bytes = new byte[(256 * 192) + 1];
7676
var IPtr = bmpData.Scan0;
7777
Marshal.Copy(IPtr, bytes, 0, 256 * 192);
78-
for (var y = 0; y < 192; y++)
78+
for (var y = 0; y <= 191; y++)
7979
{
80-
for (var x = 0; x < 256; x++)
80+
for (var x = 0; x <= 255; x++)
8181
{
8282
if (frame.Layer1[y, x])
8383
{

PPMTest/Form1.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ public void LoadPPM(string fn)
2929
ppm = new PPMFile();
3030
ppm.LoadFromFile(System.IO.Path.Combine(Path, fn));
3131
Props.SelectedObject = ppm;
32-
Thumbnail.Image = PPMRenderer.GetThumbnailBitmap(ppm.Thumbnail.Buffer);
32+
Thumbnail.Image = PPMLib.Winforms.PPMRenderer.GetThumbnailBitmap(ppm.Thumbnail.Buffer);
3333
fcnt = 0;
3434
}
3535

3636
private void FileSel_SelectedIndexChanged(object sender, EventArgs e)
3737
{
3838
LoadPPM(FileSel.SelectedItem as string);
3939
fcnt = 0;
40-
FrameViewer.Image = PPMRenderer.GetFrameBitmap(ppm.Frames[fcnt]);
40+
FrameViewer.Image = PPMLib.Winforms.PPMRenderer.GetFrameBitmap(ppm.Frames[fcnt]);
4141
}
4242

4343
private void Form1_Load(object sender, EventArgs e)
@@ -48,7 +48,7 @@ private void Form1_Load(object sender, EventArgs e)
4848
int fcnt = 0;
4949
private void NextFrameButton_Click(object sender, EventArgs e)
5050
{
51-
FrameViewer.Image = PPMRenderer.GetFrameBitmap(ppm.Frames[fcnt]);
51+
FrameViewer.Image = PPMLib.Winforms.PPMRenderer.GetFrameBitmap(ppm.Frames[fcnt]);
5252
fcnt++;
5353
if (fcnt >= ppm.FrameCount) fcnt = 0;
5454

0 commit comments

Comments
 (0)