Projekt

Obecné

Profil

Stáhnout (8.27 KB) Statistiky
| Větev: | Tag: | Revize:
1
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
}
(2-2/6)