Skip to content

Commit

Permalink
Add grid alignment form for checking the grid before painting
Browse files Browse the repository at this point in the history
  • Loading branch information
voximity committed Mar 12, 2021
1 parent 1f73055 commit dd3ad94
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 13 deletions.
28 changes: 21 additions & 7 deletions Form1.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions Form1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static BrickadiaAutoPainter.Windows;

namespace BrickadiaAutoPainter {
public partial class Form1 : Form {
Expand Down Expand Up @@ -132,5 +133,60 @@ private void paintButton_Click(object sender, EventArgs e) {
private void advancedSettingsButton_Click(object sender, EventArgs e) {
advancedSettingsForm.ShowDialog();
}

private void checkGridAlignment(object sender, EventArgs e) {
if (!topLeftPos.HasValue || !topRightPos.HasValue || !bottomLeftPos.HasValue || !bottomRightPos.HasValue) return;

int[] xs = new int[] { topLeftPos.Value.Item1, topRightPos.Value.Item1, bottomLeftPos.Value.Item1, bottomRightPos.Value.Item1 };
int[] ys = new int[] { topLeftPos.Value.Item2, topRightPos.Value.Item2, bottomLeftPos.Value.Item2, bottomRightPos.Value.Item2 };

int minX = Enumerable.Min(xs);
int minY = Enumerable.Min(ys);

int maxX = Enumerable.Max(xs);
int maxY = Enumerable.Max(ys);

int padding = 40; // padding to surround the cropped image with

Rectangle cropping = new Rectangle(minX - padding, minY - padding, maxX - minX + padding * 2, maxY - minY + padding * 2);

// take a screenshot AFTER minimizing the window
WindowState = FormWindowState.Minimized;
Thread.Sleep(500);
using Bitmap gameShot = ScreenCapture.CaptureWindow(Program.GetBrickadiaIntPtr());
WindowState = FormWindowState.Normal;

// add the grid
using Graphics graphics = Graphics.FromImage(gameShot);
SolidBrush gridMarkerBrush = new SolidBrush(Color.Gray);
SolidBrush cornerMarkerBrush = new SolidBrush(Color.Blue);

Action<Brush, int, int, int> drawPoint = (brush, x, y, r) => graphics.FillRectangle(brush, new Rectangle(x - r, y - r, r * 2, r * 2));

Perspective perspective = new Perspective(topLeftPos.Value, topRightPos.Value, bottomLeftPos.Value, bottomRightPos.Value);
int w = (int)numBricksX.Value;
int h = (int)numBricksY.Value;
for (int y = 0; y < w; y++) {
for (int x = 0; x < h; x++) {
double tx = x / (double)(w - 1);
double ty = y / (double)(h - 1);

(int, int) point = perspective.PointOn(tx, ty);
drawPoint(gridMarkerBrush, point.Item1, point.Item2, 2);
}
}

// and the corners
for (int i = 0; i < 4; i++)
drawPoint(cornerMarkerBrush, xs[i], ys[i], 5);

// finally crop the image
using Bitmap croppedGameShot = ScreenCapture.CropBitmap(gameShot, cropping);

// open the alignment form
GridAlignmentForm alignmentForm = new GridAlignmentForm();
alignmentForm.PictureBox.Image = croppedGameShot;
alignmentForm.ShowDialog();
}
}
}
84 changes: 84 additions & 0 deletions GridAlignmentForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions GridAlignmentForm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace BrickadiaAutoPainter {
public partial class GridAlignmentForm : Form {
public PictureBox PictureBox => pictureBox;

public GridAlignmentForm() {
InitializeComponent();
}

private void okButton_Click(object sender, EventArgs e) {
Close();
}
}
}
63 changes: 63 additions & 0 deletions GridAlignmentForm.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="label1.Text" xml:space="preserve">
<value>Ensure that the superimposed points match neatly with each brick. Blue dots are the corners you provided, and gray dots are assumed pixel locations. If the grid is not accurate, close this window, reset dimensions, and/or recapture corners.</value>
</data>
</root>
11 changes: 5 additions & 6 deletions Robot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class Robot : IDisposable {
private int paletteX = 0;
private int paletteY = 0;

public Perspective CreatePerspective() {
return new Perspective(TopLeft.Value, TopRight.Value, BottomLeft.Value, BottomRight.Value);
}

public void ChangePaletteColor((int, int) previous, (int, int) next) {
(int px, int py) = previous;
(int nx, int ny) = next;
Expand Down Expand Up @@ -83,14 +87,9 @@ public Bitmap GeneratePreview() {
}

public void Paint() {
(int, int) topLeft = TopLeft.Value;
(int, int) topRight = TopRight.Value;
(int, int) bottomLeft = BottomLeft.Value;
(int, int) bottomRight = BottomRight.Value;

Dictionary<(int, int), List<(int, int)>> palettePixelPair = new Dictionary<(int, int), List<(int, int)>>();

Perspective perspective = new Perspective(topLeft, topRight, bottomLeft, bottomRight);
Perspective perspective = CreatePerspective();
using Bitmap bitmap = new Bitmap(Image, new Size(Width, Height));
for (int iy = 0; iy < bitmap.Height; iy++) {
for (int ix = 0; ix < bitmap.Width; ix++) {
Expand Down
25 changes: 25 additions & 0 deletions ScreenCapture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;

namespace BrickadiaAutoPainter {
class ScreenCapture {
public static Bitmap CaptureWindow(IntPtr window) {
Windows.RECT rect = new Windows.RECT();
Windows.GetWindowRect(window, ref rect);
Rectangle rectangle = new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);

Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height);
using Graphics graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(new Point(rectangle.Left, rectangle.Top), Point.Empty, rectangle.Size);

return bitmap;
}

public static Bitmap CropBitmap(Bitmap bitmap, Rectangle cropping) {
return bitmap.Clone(cropping, PixelFormat.Format32bppArgb);
}
}
}

0 comments on commit dd3ad94

Please sign in to comment.