tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
1
ZUGRIFFE
1446
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
  1. #1
    Avatar von Alexander Schuc
    Alexander Schuc Alexander Schuc ist offline admin | crazy-weasel
    tutorials.de Administrator
    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;
                }
            }
     
        }
    }
    Miniaturansicht angehängter Grafiken Miniaturansicht angehängter Grafiken [Quiz#14] Alexander Schuc (C#)-cc14preview_dice.png  
     
    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

  2. #2
    Avatar von Sebastian Schmidt
    Sebastian Schmidt Sebastian Schmidt ist offline Mitglied Silber
    Registriert seit
    Dec 2002
    Ort
    Hannover
    Beiträge
    75
    So so, du hast also nur Frauen im Hinterkopf gehabt als du das gemacht hast wa?
     

Thema nicht erledigt

Ähnliche Themen

  1. [Quiz#15] Alexander Schuc (C#)
    Von Alexander Schuc im Forum Archiv
    Antworten: 0
    Letzter Beitrag: 05.04.10, 21:24
  2. [Quiz#13] Alexander Schuc (C#)
    Von Alexander Schuc im Forum Archiv
    Antworten: 0
    Letzter Beitrag: 17.01.10, 18:38
  3. [Quiz#11] Alexander Schuc (C#)
    Von Alexander Schuc im Forum Archiv
    Antworten: 2
    Letzter Beitrag: 24.10.09, 23:24
  4. [QUIZ#02] Alexander Schuc (C#)
    Von Alexander Schuc im Forum Archiv
    Antworten: 0
    Letzter Beitrag: 28.09.08, 14:59
  5. [QUIZ#1] Alexander Schuc (C#)
    Von Alexander Schuc im Forum Archiv
    Antworten: 0
    Letzter Beitrag: 18.09.08, 23:49