1 |
23e9ca21
|
A-Konig
|
using System;
|
2 |
|
|
using System.Collections.Generic;
|
3 |
|
|
using System.Drawing;
|
4 |
|
|
using System.Drawing.Imaging;
|
5 |
|
|
using System.IO;
|
6 |
|
|
using System.Text;
|
7 |
|
|
|
8 |
|
|
namespace TextureEditing
|
9 |
|
|
{
|
10 |
|
|
/// <summary>
|
11 |
|
|
/// Edits input pngs
|
12 |
|
|
/// </summary>
|
13 |
|
|
class MapEditor
|
14 |
|
|
{
|
15 |
|
|
/// <summary> Path to data </summary>
|
16 |
|
|
string dataPath;
|
17 |
|
|
/// <summary> Path to output folder </summary>
|
18 |
|
|
string outPath;
|
19 |
|
|
|
20 |
|
|
/// <summary>
|
21 |
|
|
/// Constructor
|
22 |
|
|
/// </summary>
|
23 |
|
|
/// <param name="dataPath">Path to data</param>
|
24 |
|
|
/// <param name="outPath">Path to output folder</param>
|
25 |
|
|
public MapEditor(string dataPath, string outPath)
|
26 |
|
|
{
|
27 |
|
|
this.dataPath = dataPath;
|
28 |
|
|
this.outPath = outPath;
|
29 |
|
|
}
|
30 |
|
|
|
31 |
|
|
/// <summary>
|
32 |
|
|
/// Crop all pngs from input data folder
|
33 |
|
|
/// </summary>
|
34 |
|
|
public void EditAllPngs()
|
35 |
|
|
{
|
36 |
|
|
// does dataPath folder exist
|
37 |
|
|
if (!Directory.Exists(dataPath))
|
38 |
|
|
{
|
39 |
|
|
Console.WriteLine("Path does not exist");
|
40 |
|
|
return;
|
41 |
|
|
}
|
42 |
|
|
|
43 |
|
|
List<PngEdited> cropped = new List<PngEdited>();
|
44 |
|
|
|
45 |
|
|
// for all files
|
46 |
|
|
string[] files = Directory.GetFiles(dataPath);
|
47 |
|
|
foreach (string f in files)
|
48 |
|
|
{
|
49 |
|
|
Console.WriteLine("Processing file " + f);
|
50 |
|
|
Bitmap img = new Bitmap(f);
|
51 |
|
|
var newpng = Crop(img);
|
52 |
|
|
newpng.name = Path.GetFileName(f);
|
53 |
|
|
PositionInOriginal(img, newpng);
|
54 |
|
|
PositionOfCentroid(newpng);
|
55 |
|
|
cropped.Add(newpng);
|
56 |
|
|
|
57 |
|
|
newpng.Save(outPath + "/" + newpng.name);
|
58 |
|
|
}
|
59 |
|
|
SaveTxt(cropped);
|
60 |
|
|
|
61 |
|
|
/*
|
62 |
|
|
int c = 0;
|
63 |
|
|
foreach (PngEdited p in cropped)
|
64 |
|
|
{
|
65 |
|
|
c++;
|
66 |
|
|
TestImage(p, c);
|
67 |
|
|
}
|
68 |
|
|
*/
|
69 |
|
|
}
|
70 |
|
|
|
71 |
|
|
/// <summary>
|
72 |
|
|
/// Testing method
|
73 |
|
|
/// Prints out cropped image positioned back to original map and image with visible centroid
|
74 |
|
|
/// </summary>
|
75 |
|
|
/// <param name="pngEdited">Output image</param>
|
76 |
|
|
/// <param name="i">Number of image</param>
|
77 |
|
|
private void TestImage(PngEdited pngEdited, int i)
|
78 |
|
|
{
|
79 |
|
|
Bitmap png = new Bitmap("./bory-buildings.png");
|
80 |
|
|
Bitmap newpng = pngEdited.png;
|
81 |
|
|
|
82 |
|
|
Bitmap centroid = new Bitmap(20, 20);
|
83 |
|
|
for (int h = 0; h < centroid.Height; h++)
|
84 |
|
|
for (int w = 0; w < centroid.Width; w++)
|
85 |
|
|
centroid.SetPixel(w, h, Color.Red);
|
86 |
|
|
|
87 |
|
|
|
88 |
|
|
int xPos = (int)((newpng.Width / 100.0f) * pngEdited.xCentr) - 10;
|
89 |
|
|
int yPos = (int)((newpng.Height / 100.0f) * (100 - pngEdited.yCentr)) - 10;
|
90 |
|
|
|
91 |
|
|
Bitmap centroidTest = new Bitmap(newpng.Width, newpng.Height);
|
92 |
|
|
using (Graphics g = Graphics.FromImage(centroidTest))
|
93 |
|
|
{
|
94 |
|
|
g.DrawImage(newpng, new Rectangle(0, 0, newpng.Width, newpng.Height), new Rectangle(0, 0, newpng.Width, newpng.Height), GraphicsUnit.Pixel);
|
95 |
|
|
g.DrawImage(centroid, new Rectangle(xPos, yPos, 20, 20), new Rectangle(0, 0, centroidTest.Width, centroidTest.Height), GraphicsUnit.Pixel);
|
96 |
|
|
|
97 |
|
|
centroidTest.Save($"testCentroidOut{i}.png", ImageFormat.Png);
|
98 |
|
|
}
|
99 |
|
|
|
100 |
|
|
for (int h = 0; h < newpng.Height; h++)
|
101 |
|
|
for (int w = 0; w < newpng.Width; w++)
|
102 |
|
|
{
|
103 |
|
|
if (newpng.GetPixel(w, h).A != 0)
|
104 |
|
|
{
|
105 |
|
|
newpng.SetPixel(w, h, Color.Red);
|
106 |
|
|
}
|
107 |
|
|
}
|
108 |
|
|
|
109 |
|
|
xPos = (int) ((png.Width / 100.0f) * pngEdited.xPerc);
|
110 |
|
|
yPos = (int)((png.Height / 100.0f) * (100-pngEdited.yPerc)) - newpng.Height;
|
111 |
|
|
|
112 |
|
|
using (Graphics g = Graphics.FromImage(png))
|
113 |
|
|
{
|
114 |
|
|
g.DrawImage(newpng, new Rectangle(xPos, yPos, newpng.Width, newpng.Height), new Rectangle(0, 0, newpng.Width, newpng.Height), GraphicsUnit.Pixel);
|
115 |
|
|
png.Save($"testOut{i}.png", ImageFormat.Png);
|
116 |
|
|
}
|
117 |
|
|
}
|
118 |
|
|
|
119 |
|
|
/// <summary>
|
120 |
|
|
/// Compute the position of centroid. Coordinates are computed in % from bottom left corner of cropped png
|
121 |
|
|
/// </summary>
|
122 |
|
|
/// <param name="newpng">Output png in instance PngEdited</param>
|
123 |
|
|
private void PositionOfCentroid(PngEdited newpng)
|
124 |
|
|
{
|
125 |
|
|
// from all non transparent pixels
|
126 |
|
|
int coordY = 0, coordX = 0;
|
127 |
|
|
int count = 0;
|
128 |
|
|
for (int h = 0; h < newpng.png.Height; h++)
|
129 |
|
|
for (int w = 0; w < newpng.png.Width; w++)
|
130 |
|
|
{
|
131 |
|
|
if (newpng.png.GetPixel(w, h).A != 0 )
|
132 |
|
|
{
|
133 |
|
|
count++;
|
134 |
|
|
coordY += h;
|
135 |
|
|
coordX += w;
|
136 |
|
|
}
|
137 |
|
|
}
|
138 |
|
|
|
139 |
|
|
// coordinates
|
140 |
|
|
newpng.xCentr = coordX / count;
|
141 |
|
|
newpng.yCentr = coordY / count;
|
142 |
|
|
|
143 |
|
|
// to %
|
144 |
|
|
float onePercX = newpng.png.Width / 100.0f;
|
145 |
|
|
float percX = newpng.xCentr / onePercX;
|
146 |
|
|
newpng.xCentr = percX;
|
147 |
|
|
|
148 |
|
|
float onePercY = newpng.png.Height / 100.0f;
|
149 |
|
|
float percY = 100 - (newpng.yCentr / onePercY);
|
150 |
|
|
newpng.yCentr = percY;
|
151 |
|
|
}
|
152 |
|
|
|
153 |
|
|
/// <summary>
|
154 |
|
|
/// Find the position of cropped image in original. Coordinates of bottom left corner are computed in % from bottom left corner of original
|
155 |
|
|
/// </summary>
|
156 |
|
|
/// <param name="img">Original</param>
|
157 |
|
|
/// <param name="newpng">New image</param>
|
158 |
|
|
private void PositionInOriginal(Bitmap img, PngEdited newpng)
|
159 |
|
|
{
|
160 |
|
|
// left bottom corner
|
161 |
|
|
int xLeft = newpng.xStart;
|
162 |
|
|
int yLeft = newpng.yEnd;
|
163 |
|
|
|
164 |
|
|
// compute percentages
|
165 |
|
|
float onePercX = img.Width / 100.0f;
|
166 |
|
|
float percX = xLeft / onePercX;
|
167 |
|
|
newpng.xPerc = percX;
|
168 |
|
|
|
169 |
|
|
float onePercY = img.Height / 100.0f;
|
170 |
|
|
float percY = 100 - (yLeft / onePercY);
|
171 |
|
|
newpng.yPerc = percY;
|
172 |
|
|
}
|
173 |
|
|
|
174 |
|
|
/// <summary>
|
175 |
|
|
/// Save information about output files as csv
|
176 |
|
|
/// [name];[x coordinate of bottom left corner];[y coordinate of bottom left corner];[x coordinate of centroid];[y coordinate of centroid]
|
177 |
|
|
/// Coordinates of bottom left corner are computed in % from bottom left corner of original, coordinates of centroid are computed in % from bottom left corner of output png
|
178 |
|
|
/// </summary>
|
179 |
|
|
/// <param name="cropped"></param>
|
180 |
|
|
private void SaveTxt(List<PngEdited> cropped)
|
181 |
|
|
{
|
182 |
|
|
string res = "";
|
183 |
|
|
|
184 |
|
|
foreach (PngEdited png in cropped)
|
185 |
|
|
res += $"{png.name};{png.xPerc};{png.yPerc};{png.xCentr};{png.yCentr}\n";
|
186 |
|
|
|
187 |
|
|
File.WriteAllBytes(outPath + "/output.csv", Encoding.ASCII.GetBytes(res));
|
188 |
|
|
}
|
189 |
|
|
|
190 |
|
|
/// <summary>
|
191 |
|
|
/// Crop image so it does not contain any transparent padding
|
192 |
|
|
/// </summary>
|
193 |
|
|
/// <param name="img">Original image</param>
|
194 |
|
|
/// <returns>Cropped image as PngEdited instance</returns>
|
195 |
|
|
private PngEdited Crop(Bitmap img)
|
196 |
|
|
{
|
197 |
|
|
PngEdited res = new PngEdited();
|
198 |
|
|
|
199 |
|
|
int xFrom = img.Width, xTo = 0;
|
200 |
|
|
int yFrom = img.Height, yTo = 0;
|
201 |
|
|
|
202 |
|
|
// find start + end of x and y
|
203 |
|
|
for (int h = 0; h < img.Height; h++)
|
204 |
|
|
for (int w = 0; w < img.Width; w++)
|
205 |
|
|
{
|
206 |
|
|
if (img.GetPixel(w, h).A != 0 && xFrom > w)
|
207 |
|
|
xFrom = w;
|
208 |
|
|
|
209 |
|
|
if (img.GetPixel(w, h).A != 0 && xTo < w)
|
210 |
|
|
xTo = w;
|
211 |
|
|
|
212 |
|
|
if (img.GetPixel(w, h).A != 0 && yFrom > h)
|
213 |
|
|
yFrom = h;
|
214 |
|
|
|
215 |
|
|
if (img.GetPixel(w, h).A != 0 && yTo < h)
|
216 |
|
|
yTo = h;
|
217 |
|
|
}
|
218 |
|
|
|
219 |
|
|
|
220 |
|
|
// crop
|
221 |
|
|
Bitmap cropped = new Bitmap(xTo - xFrom + 1, yTo - yFrom + 1);
|
222 |
|
|
using (Graphics g = Graphics.FromImage(cropped))
|
223 |
|
|
{
|
224 |
|
|
g.DrawImage(img, new Rectangle(0, 0, cropped.Width, cropped.Height), new Rectangle(xFrom, yFrom, cropped.Width, cropped.Height), GraphicsUnit.Pixel);
|
225 |
|
|
res.png = cropped;
|
226 |
|
|
}
|
227 |
|
|
|
228 |
|
|
res.xStart = xFrom;
|
229 |
|
|
res.xEnd = xTo;
|
230 |
|
|
res.yStart = yFrom;
|
231 |
|
|
res.yEnd = yTo;
|
232 |
|
|
|
233 |
|
|
return res;
|
234 |
|
|
}
|
235 |
|
|
|
236 |
|
|
}
|
237 |
|
|
}
|