ERLEDIGT
NEIN
NEIN
ANTWORTEN
1
1
ZUGRIFFE
1446
1446
EMPFEHLEN
-
27.03.10 16:55 #1
- Registriert seit
- Aug 2001
- Ort
- Österreich, Stmk, Graz
- Beiträge
- 2.783
Hoi..

Auch von mir gibts eine kleine Lösung.

(Bild von DeviantArt: Dice by suicidegirls)
Kurze Anmerkung zum Ablauf meines Programms:
Nach Laden des Bildes wird es in ein Graustufenbild (bzw. Luma) umgewandelt, größter und kleinster Helligkeitswert
gesucht, und daraufhin in ein "Würfelbild" umgewandelt. Die Ausgabe ist immer ein (ungefähr) gleich großes Bild, da
ich mir pro Würfel einen gleich großen Bereich im originalen Bild ansehe und davon den Durchschnittswert nehme.
Damit die Laufzeit des Programms nicht zu lang ist, hab ich auf unsafe Code zurück gegriffen und mit BitmapData
gearbeitet, anstatt mit den langsamen Methoden der Graphics Klasse. Abgesehen vom Zusammenstückeln der
Würfelgrafiken, das klappt damit bequemer.
Ein Dank geht an Matthias.. hab deine Würfel verwendet, war zu faul selber welche zu basteln.
Verwendung
Es wurde eine Extension Method namens "GetDiced" erstellt, welche die Umwandlung vornimmt.
Code csharp:1 2
Bitmap original = Bitmap.FromFile(...); Bitmap diced = original.GetDiced(12);
Wenn man das Beispielprogramm verwendet, kann man durch Klick auf die erste Box ein Bild laden. Dieses wird
automatisch in ein Würfelbild gewandelt. Einstellungen also vor dem Laden vornehmen. Aktiviert man "Luma" bekommt
man das Luma Bild angezeigt.
Zum Speichern des Ergebnisses klickt man auf die 2. PictureBox. Gespeichert wird immer als PNG Datei, deswegen
Dateierweiterung entsprechend selber angeben.
Anhänge
Projektdateien für VisualStudio 2010
(bei anderen Versionen einfach die Codedateien in ein WindowsForms Projekte übernehmen)
CodingQuiz14.zip
Ausführbare Dateien
CodingQuiz14-Bin.zip
Code
Code csharp:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Drawing.Imaging; using System.IO; namespace CodingQuiz14 { public static class DiceGraphics { public static Bitmap GetDiced(this Bitmap source, int size) { try { Image[] parts = LoadDices(size); if (parts == null) return null; Bitmap luma = source.GetLuma(); int[] range = FindRange(luma); byte[,] diceData = GetDices(luma, range, size); int dw = diceData.GetLength(0); int dy = diceData.GetLength(1); Bitmap diceBmp = new Bitmap(dw * size, dy * size); using (Graphics gfx = Graphics.FromImage(diceBmp)) { for (int x = 0; x < dw; x++) for (int y = 0; y < dy; y++) { gfx.DrawImageUnscaled(parts[diceData[x, y]], x * size, y * size, size, size); } } return diceBmp; } catch (Exception ex) { Console.Write(ex.Message); } return null; } private static unsafe byte[,] GetDices(Bitmap source, int[] range, int size) { int dynamic = range[1] - range[0]; double stepsize = (dynamic+1) / 6.0; byte[,] data = new byte[(source.Width / size) + 1, (source.Height / size) + 1]; BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); unsafe { byte avg, d; for (int y = 0; y < source.Height; y += size) for (int x = 0; x < source.Width; x += size) { avg = Average(sourceData, x, y, size); d = (byte)((avg - range[0]) / stepsize); data[x / size, y / size] = (byte)((byte)5 - d); } } source.UnlockBits(sourceData); return data; } private static unsafe byte Average(BitmapData data, int x, int y, int size) { int sum = 0; int c = 0; byte* row; for (int yc = y; yc < y + size; yc++) { if (yc >= data.Height) break; row = (byte*)data.Scan0 + (yc * data.Stride); for (int xc = x; xc < x + size; xc++) { if (xc >= data.Width) break; sum += *(row + xc); c++; } } return (byte)(sum / c); } public static Bitmap GetLuma(this Bitmap source) { Bitmap lumaBmp = new Bitmap(source.Width, source.Height, PixelFormat.Format8bppIndexed); ColorPalette p = lumaBmp.Palette; for (int i = 0; i < 256; i++) { p.Entries[i] = Color.FromArgb(i, i, i); } lumaBmp.Palette = p; BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); BitmapData lumaData = lumaBmp.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); unsafe { byte r, g, b, luma; byte* pixel, luminaPixel, row; for (int y = 0; y < source.Height; y++) { row = (byte*) (sourceData.Scan0 + (y * sourceData.Stride)); for (int x = 0; x < source.Width; x++) { pixel = row + x*3; r = pixel[2]; g = pixel[1]; b = pixel[0]; luma = (byte)(0.2126 * (double)r + 0.7152 * (double)g + 0.0722 * (double)b); luminaPixel = (byte*)lumaData.Scan0 + (y * lumaData.Stride) + x; (*luminaPixel) = luma; } } } source.UnlockBits(sourceData); lumaBmp.UnlockBits(lumaData); return lumaBmp; } private static int[] FindRange(Bitmap source) { if (source.PixelFormat != PixelFormat.Format8bppIndexed) return new int[] { 0, 255 }; BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); int[] data = new int[] { int.MaxValue, int.MinValue }; unsafe { byte pixel; byte* row; for (int y = 0; y < source.Height; y++) { row = (byte*)sourceData.Scan0 + (y * sourceData.Stride); for (int x = 0; x < source.Width; x++) { pixel = *(row + x); if (pixel < data[0]) data[0] = pixel; if (pixel > data[1]) data[1] = pixel; } } } source.UnlockBits(sourceData); return data; } private static Image[] LoadDices(int size) { string dicefile = string.Format(".\\dices\\dice{0}.png", size); if (!File.Exists(dicefile)) { return null; } try { using (Image dices = Bitmap.FromFile(dicefile)) { Image[] parts = new Image[6]; for (int i = 0; i < 6; i++) { parts[i] = new Bitmap(size, size); using (Graphics gfx = Graphics.FromImage(parts[i])) { gfx.DrawImage(dices, new Rectangle(0, 0, size, size), new Rectangle(0, i*size, size, size), GraphicsUnit.Pixel); } } return parts; } } catch (Exception ex) { return null; } } } }
With the first link the chain is forged. The first speech censored, the first thought forbidden, the first freedom denied, chains us all irrevocably.
Aaron Satie
Legends... are the spice of the universe, Mr. Data, because they have a way of sometimes coming true.
Captain Jean-Luc Picard, Stardate ~41294.5
Tutorials.de chattet. Hier gibts auch .net Support ^^
Klickt auf chattet und nutzt den Webchat, oder verbindet euch zu irc.tutorials.de - Channel #Tutorials.de
(moo)blog furred.net // SiteInfo für WP7 // Pastebin für WP7 // BlogEngine.net Extensions
-
28.03.10 14:22 #2
So so, du hast also nur Frauen im Hinterkopf gehabt als du das gemacht hast wa?
Ähnliche Themen
-
[Quiz#15] Alexander Schuc (C#)
Von Alexander Schuc im Forum ArchivAntworten: 0Letzter Beitrag: 05.04.10, 21:24 -
[Quiz#13] Alexander Schuc (C#)
Von Alexander Schuc im Forum ArchivAntworten: 0Letzter Beitrag: 17.01.10, 18:38 -
[Quiz#11] Alexander Schuc (C#)
Von Alexander Schuc im Forum ArchivAntworten: 2Letzter Beitrag: 24.10.09, 23:24 -
[QUIZ#02] Alexander Schuc (C#)
Von Alexander Schuc im Forum ArchivAntworten: 0Letzter Beitrag: 28.09.08, 14:59 -
[QUIZ#1] Alexander Schuc (C#)
Von Alexander Schuc im Forum ArchivAntworten: 0Letzter Beitrag: 18.09.08, 23:49






Login





