okay images are now dithered in the absolute messiest way

This commit is contained in:
Maff 2019-10-04 21:14:50 +01:00
parent 8e55652567
commit 85ff23a1f9
9 changed files with 96 additions and 87 deletions

View File

@ -1,13 +0,0 @@
using System.Drawing;
namespace libdither.Algorithms {
internal abstract class Base : IDither {
private uint bwThresh;
public uint BlackPoint { get => bwThresh; set => bwThresh = value; }
//Do nothing for the dither method because it's a dummy
public abstract Bitmap Dither(Bitmap input);
internal static int Clamp(int input) => Clamp(input, 0, 255);
internal static int Clamp(int input, int min, int max) => (input < min) ? min : (input > max) ? max : input;
}
}

View File

@ -1,23 +0,0 @@
using System.Drawing;
namespace libdither.Algorithms {
internal abstract class Ordered : Base {
private readonly byte[,] matrix;
private readonly byte hSzMx;
private readonly byte wSzMx;
internal protected Ordered(byte[,] input) {
hSzMx = (byte)(input.GetUpperBound(1) + 1);
wSzMx = (byte)(input.GetUpperBound(0) + 1);
int maxMx=wSzMx*hSzMx;
int scMx=255/maxMx;
matrix = new byte[hSzMx, wSzMx];
for(int x = 0; x < wSzMx; x++)
for(int y = 0; y < hSzMx; y++)
matrix[x, y] = (byte)Clamp(input[x, y] * scMx);
}
public override Bitmap Dither(Bitmap input) {
int rC; int cC; byte tC;
cC
}
}
}

View File

@ -1,8 +0,0 @@
using System.Drawing;
namespace libdither {
public interface IDither {
uint BlackPoint { get; set; }
Bitmap Dither(Bitmap input);
}
}

View File

@ -1,27 +0,0 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace libdither {
public static class ImageTransforms {
public static Bitmap ConvertTo1Bit(Bitmap input) => input;
public static byte[] Convert1BitToByteArray(Bitmap input) {
int hSz=input.Height; int wSz=input.Width;
byte[] intermed;
using(MemoryStream ms = new MemoryStream()) {
input.Save(ms, ImageFormat.Bmp);
input.Dispose();
intermed = ms.ToArray();
}
byte[] output=new byte[hSz*wSz];
int hdrOffset=intermed.Length-output.Length;
for(int h = 0; h < hSz; h++) {
for(int w = 0; w < wSz; w++) {
output[(wSz * (hSz - 1 - h)) + (wSz - 1 - w)] =
(byte)~intermed[hdrOffset + (wSz * h) + (wSz - 1 - w)];
}
}
return output;
}
}
}

View File

@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="4.6.0" />
</ItemGroup>
</Project>

View File

@ -10,7 +10,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "paperangapp", "paperangapp\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "libpaperang", "libpaperang\libpaperang.csproj", "{A429CCEB-9331-4CD9-B3C0-A8F736732DEA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "liblogtiny", "liblogtiny\liblogtiny.csproj", "{B7D242A8-F9DE-450B-9C87-5519CA782193}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "liblogtiny", "liblogtiny\liblogtiny.csproj", "{B7D242A8-F9DE-450B-9C87-5519CA782193}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -17,9 +17,34 @@ namespace paperangapp {
private ILogTiny logger;
private BaseTypes.Connection mmjcx=BaseTypes.Connection.USB;
private BaseTypes.Model mmjmd=BaseTypes.Model.None;
private IPrinter prtr=new USB(BaseTypes.Model.None); // T1 used as a generic, prtr used soley for the PrinterAvailable attr. all paperang devices tested report the exact same USB identifiers.
private IPrinter prtr=new USB(BaseTypes.Model.None);
private Paperang mmj=null;
private System.Timers.Timer usbpoll;
byte[,] bayer2 = {
{ 0, 2 },
{ 3, 1 }
};
byte[,] bayer3 = {
{ 0, 7, 3 },
{ 6, 5, 2 },
{ 4, 1, 8 }
};
byte[,] bayer4 = {
{ 0, 8, 2, 10 },
{ 12, 4, 14, 6 },
{ 3, 11, 1, 9 },
{ 15, 7, 13, 5 }
};
byte[,] bayer8 = {
{ 0, 48, 12, 60, 3, 51, 15, 63 },
{ 32, 16, 44, 28, 35, 19, 47, 31 },
{ 8, 56, 4, 52, 11, 59, 7, 55 },
{ 40, 24, 36, 20, 43, 27, 39, 23 },
{ 2, 50, 14, 62, 1, 49, 13, 61 },
{ 34, 18, 46, 30, 33, 17, 45, 29 },
{ 10, 58, 6, 54, 9, 57, 5, 53 },
{ 42, 26, 38, 22, 41, 25, 37, 21 }
};
//private uint dThresh=127;
private enum AppState {
UnInitNoDev,
@ -28,6 +53,7 @@ namespace paperangapp {
};
private AppState state=AppState.UnInitDev;
// TODO: is it out of scope for this library to provide functionality for printing bitmap data?
private byte Clamp(int v) => Convert.ToByte(v < 0 ? 0 : v > 255 ? 255 : v);
public MainWindow() {
InitializeComponent();
logger = new LUITextbox();
@ -39,6 +65,46 @@ namespace paperangapp {
usbpoll.Elapsed += EvtUsbPoll;
usbpoll.Start();
logger.Verbose("USB presence interval event started");
byte _szW; byte _szH; int _szM; int _sc;
//bayer2
_szW = (byte)(bayer2.GetUpperBound(1) + 1);
_szH = (byte)(bayer2.GetUpperBound(0) + 1);
_szM = _szW * _szH;
_sc = 255 / _szM;
for(int mx = 0; mx < _szW; mx++) {
for(int my = 0; my < _szH; my++)
bayer2[mx, my] = Clamp(bayer2[mx, my] * _sc);
}
//bayer3
_szW = (byte)(bayer3.GetUpperBound(1) + 1);
_szH = (byte)(bayer3.GetUpperBound(0) + 1);
_szM = _szW * _szH;
_sc = 255 / _szM;
for(int mx = 0; mx < _szW; mx++) {
for(int my = 0; my < _szH; my++)
bayer3[mx, my] = Clamp(bayer3[mx, my] * _sc);
}
//bayer4
_szW = (byte)(bayer4.GetUpperBound(1) + 1);
_szH = (byte)(bayer4.GetUpperBound(0) + 1);
_szM = _szW * _szH;
_sc = 255 / _szM;
for(int mx = 0; mx < _szW; mx++) {
for(int my = 0; my < _szH; my++)
bayer4[mx, my] = Clamp(bayer4[mx, my] * _sc);
}
//bayer8
_szW = (byte)(bayer8.GetUpperBound(1) + 1);
_szH = (byte)(bayer8.GetUpperBound(0) + 1);
_szM = _szW * _szH;
_sc = 255 / _szM;
for(int mx = 0; mx < _szW; mx++) {
for(int my = 0; my < _szH; my++)
bayer8[mx, my] = Clamp(bayer8[mx, my] * _sc);
}
}
private void EvtUsbPoll(object sender, ElapsedEventArgs e) => _ = Dispatcher.BeginInvoke(new invDgtUsbPoll(DgtUsbPoll));
@ -140,7 +206,7 @@ namespace paperangapp {
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
TextRenderer.DrawText(g, text, fnt, new System.Drawing.Point(0, 0), Color.Black, tf);
g.Flush();
await Task.Run(() => PrintBitmap(b));
await Task.Run(() => PrintBitmap(b, false));
g.Dispose();
b.Dispose();
}
@ -166,7 +232,7 @@ namespace paperangapp {
logger.Debug($"Loaded image '{fn}'");
logger.Debug("Disposed of dialog");
Bitmap bimg=new Bitmap(_, mmj.Printer.LineWidth*8,
(int)(mmj.Printer.LineWidth*8*(double)((double)_.Height/(double)_.Width)));
(int)(mmj.Printer.LineWidth*8*((double)_.Height/_.Width)));
logger.Debug("Loaded image as Bitmap");
_.Dispose();
logger.Debug("Disposed of Image");
@ -175,7 +241,18 @@ namespace paperangapp {
await Task.Run(() => PrintBitmap(bmg));
bmg.Dispose();
}
private async Task PrintBitmap(Bitmap bimg) {
private async Task PrintBitmap(Bitmap bimg, bool dither = true) {
if(dither) {
logger.Trace("Dithering input bitmap");
bimg = AForge.Imaging.Filters.Grayscale.CommonAlgorithms.Y.Apply(bimg);
AForge.Imaging.Filters.OrderedDithering f = new
AForge.Imaging.Filters.OrderedDithering(bayer4);
//f.FormatTranslations.Clear();
//f.FormatTranslations[PixelFormat.Format1bppIndexed] = PixelFormat.Format1bppIndexed;
bimg = f.Apply(bimg);
//bimg = new Accord.Imaging.Filters.BayerDithering().Apply(bimg);
logger.Debug("Dithered Bitmap");
}
bimg = CopyToBpp(bimg);
logger.Debug("Converted Bitmap to 1-bit");
int hSzImg=bimg.Height;

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AForge" version="2.2.5" targetFramework="net472" />
<package id="AForge.Imaging" version="2.2.5" targetFramework="net472" />
<package id="AForge.Math" version="2.2.5" targetFramework="net472" />
<package id="LibUsbDotNet" version="2.2.29" targetFramework="net472" />
<package id="System.Collections" version="4.3.0" targetFramework="net472" />
<package id="System.Collections.Specialized" version="4.3.0" targetFramework="net472" />

View File

@ -33,6 +33,8 @@
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -70,6 +72,15 @@
<SignManifests>false</SignManifests>
</PropertyGroup>
<ItemGroup>
<Reference Include="AForge, Version=2.2.5.0, Culture=neutral, PublicKeyToken=c1db6ff4eaa06aeb, processorArchitecture=MSIL">
<HintPath>..\packages\AForge.2.2.5\lib\AForge.dll</HintPath>
</Reference>
<Reference Include="AForge.Imaging, Version=2.2.5.0, Culture=neutral, PublicKeyToken=ba8ddea9676ca48b, processorArchitecture=MSIL">
<HintPath>..\packages\AForge.Imaging.2.2.5\lib\AForge.Imaging.dll</HintPath>
</Reference>
<Reference Include="AForge.Math, Version=2.2.5.0, Culture=neutral, PublicKeyToken=abba2e25397ee8c9, processorArchitecture=MSIL">
<HintPath>..\packages\AForge.Math.2.2.5\lib\AForge.Math.dll</HintPath>
</Reference>
<Reference Include="LibUsbDotNet.LibUsbDotNet, Version=2.2.0.0, Culture=neutral, PublicKeyToken=c677239abe1e02a9, processorArchitecture=MSIL">
<HintPath>..\packages\LibUsbDotNet.2.2.29\lib\net45\LibUsbDotNet.LibUsbDotNet.dll</HintPath>
</Reference>