Autor Beitrag
Marc Dirk
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: Mi 31.03.10 13:01 
Hallo,

gibt es in C# Boardmittel oder eine einbindbare API, welche mir Bildverarbeitungsprozesse wie in GIMP ermöglicht, bzw. kann man die GIMP API von C# aus nutzen?
Ich möchte gerne ein Programm in C# schreiben welches programmgesteuert Bilder aus einem Verzeichnis lädt, bearbeitet (2D Bild in den Raum rein verzerren, quasi 3D machen) und wieder abspeichert.
Hat jemand nützliche Tipps?

Im voraus vielen Dank für Eure Tipps und viele Grüsse

Marc

Moderiert von user profile iconNarses: "gelöst!" aus dem Titel entfernt, dafür das Flag im Thread gesetzt.


Zuletzt bearbeitet von Marc Dirk am Di 06.04.10 17:59, insgesamt 2-mal bearbeitet
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Mi 31.03.10 18:00 
Also ich habe mal Bilderkennung mit OpenCV gemacht. Da gibt es solche Funktionen, um ein Draufsicht von einem Bild zu generieren. Ich schätze aber mal, das ist ein bißchen überdimensioniert.
Marc Dirk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: Do 01.04.10 17:24 
Hallo Norman,

ich habs mir angesehen und geb Dir recht.
Aber es kann doch nicht sein das es keine API oder so etwas für diese Zwecke gibt.
Ich habe mit Paint.Net auch angesehen, da OpenSource und in C# aber hier gibt es keine Bildverzerrungen.
Es ist zum verrückt werden. Kann man sowas nicht mit DirectX lösen oder die GIMP API irgendwie ansprechen?

Gruß
Marc
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Do 01.04.10 19:30 
Um was für einen Effekt geht es denn nun genau, so etwas wie bei Apples Coverflow? Das ist ja noch eine relativ einfache Projektion, die mit zwei Schleifen schnell umgesetzt werden kann. In der Zeit hast du ja noch nicht einmal das DX-SDK heruntergeladen :nixweiss: .
Jetzt warte ich aber erst einmal ab, ob es wirklich das Richtige ist ;) .

_________________
>λ=
Marc Dirk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: So 04.04.10 10:44 
Hallo Kha,

Cowerflow, genau das bringt es auf den Punkt. Ich hatte den Begriff vorher nie gehört. Ich habe mal ein bisschen gegoogelt und das hier gefunden:
www.video-flash.de/w...w-flex-component.jpg

Im Prinzip suche ich so etwas. Ich möchte meine Artikelbilder auf schwarzem Hintergrund in den Raum rein verzerren und die Spiegelung darstellen,
also als ob das Bild auf einer spiegelnden Fläche steht. Mit Gimp ist das ganz einfach aber so kann ich unmöglich tausende Bilder bearbeiten.
Deshalb wollte ich es gerne in C# automatisieren, aber ich habe keinen Plan wie das gehen könnte und im Netz kann ich einfach nichts finden.

Wenn Du hierfür wieder Ideen oder bereits fertige Code-Beispiele hast, dann wäre ich Dir unendlich dankbar.

Gruß
Marc
huuuuuh
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 665
Erhaltene Danke: 19

win xp, (win vista), win 7
VS 2008 Express Edition, VS 2010 Express Edition, VS 2010 Professionell
BeitragVerfasst: So 04.04.10 11:38 
schau dir ma das an
www.renewendel.de/?p=117
zwar nich über C#, aber automatisches bearbeiten deiner 1000 bilder...
Marc Dirk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: So 04.04.10 15:40 
Hallo huuuuuh,
ich habe mir die Seite angesehen. Das PlugIn kann zwar Stapelverarbeitung aber nicht das Verzerren oder Spiegeln der Bilder.
Für den gewünschten Zweck ist das Tool leider nicht geeignet. Aber dennoch vielen Dank. Ich kann es sicher mal für andere Zwecke nutzen.
Gruß
Marc
:D
Marc Dirk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: Mo 05.04.10 13:13 
Hat sich schon mal jemand mit der Viewport3D-Klasse auseinander gesetzt?
Gruß
Marc
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 05.04.10 13:50 
WPF steht dir zur Verfügung? Ist zwar nicht zur reinen Bildbearbeitung ohne Anzeigen gedacht, aber damit sollte es sich doch relativ schnell lösen lassen :D . Am besten fängst du wahrscheinlich hier an: msdn.microsoft.com/e...ibrary/ms747437.aspx

_________________
>λ=
ThoMa
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46
Erhaltene Danke: 3



BeitragVerfasst: Mo 05.04.10 14:16 
Hallo,

das was Du suchst stellt Dir GDI+ schon zur Verfügung. Stichwort Image Transformation. Damit kann man Bilder skalieren, rotieren, verzerren und spiegeln. Das ganze läuft über ein Matrixobjekt. Dieses Matrixobjekt stellt dann die entsprechenden Methoden zur Verfügung und auf das Graphic-Objekt wird dann die Transformation anhand der Transformationsmatrix realisiert.

Guck mal in der MSDN-Library nach der Matrix-Klasse, da solltest Du fündig werden (Namespace System.Drawing.Drawing2D).

Grüße
ThoMa
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 05.04.10 14:59 
Affine Transformationen werden hier aber nicht genügen.

_________________
>λ=
ThoMa
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46
Erhaltene Danke: 3



BeitragVerfasst: Mo 05.04.10 15:04 
Hallo Kha,

guck Dir mal die Matrix-Methoden an, da wirst Du auch Methoden finden, die nicht-affine Transformationen zur Verfügung stellen. Sonst bekäme man die perspektivische Verzerrung ja auch nicht hin. :-)

Grüße
ThoMa
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 05.04.10 15:28 
Da ich mit Matrixtransformationen bis jetzt noch überhaupt nichts anfangen kann, befinde ich mich wahrscheinlich gerade etwas im Nachteil :D , aber selbst wenn ich mir den wohl allgemeinsten Konstruktor ansehe, finde ich nur:
msdn.microsoft.com/e...25%28v=VS.85%29.aspx hat folgendes geschrieben:
Creates and initializes a Matrix::Matrix object based on six numbers that define an affine transformation.

_________________
>λ=
Marc Dirk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: Mo 05.04.10 15:45 
Wow, das ist jetzt ein bischen viel auf einmal.
Hat einer von Euch auch ein Code-Beispiel aus dem ich lernen kann?
Gruß
Marc
ThoMa
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46
Erhaltene Danke: 3



BeitragVerfasst: Mo 05.04.10 17:27 
Hallo Kha,

Du hast völlig Recht und ich behaupte ab sofort das Gegenteil!

Mit GDI+ gehen nur affine Transformationen.

Grüße
ThoMa
Marc Dirk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: Mo 05.04.10 20:25 
So, die reine Verzerrung klappt jetzt schon mal dank dieser DLL von www.vcskicks.com/image-distortion.php !
Marc Dirk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41



BeitragVerfasst: Di 06.04.10 17:34 
So habe ich das Ganze nun gelöst:

ausblenden volle Höhe C#-Quelltext
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:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using QuadrilateralDistortion;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        
        static public Bitmap Copy(Bitmap srcBitmap)
        {
            // Simply use the constructor to create and return a copy
            return new Bitmap(srcBitmap);
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            // Artikelbild laden
            Bitmap ImageTop = new Bitmap("C:\\Artikelbild.jpg");
            // Teilkopie vom Artikelbild erstellen und spiegeln
            Bitmap ImageBottom = new Bitmap(ImageTop.Size.Width, ImageTop.Size.Height / 5);
            ImageBottom = Copy(ImageTop);
            ImageBottom.RotateFlip(RotateFlipType.RotateNoneFlipY);
            Graphics grImageBottom = Graphics.FromImage(ImageBottom);
            // Gradienten erstellen welcher von Transparent zu Weiß verläuft
            Color color = Color.Black;
            Color veryTransparentColor = Color.FromArgb(0, color.R, color.G, color.B);
            LinearGradientBrush gradient = new LinearGradientBrush(new Rectangle(00, ImageTop.Size.Width, ImageTop.Size.Height / 5), veryTransparentColor, Color.White, 90);
            Blend blend = new Blend();
            // Gradient wird nichtlinear 
            blend.Factors = new float[] { 00.05f0.1f0.15f0.2f0.25f0.3f0.35f0.4f0.45f0.5f0.58f0.66f0.74f0.82f0.86f0.90f0.94f0.96f0.98f1.0f };
            blend.Positions = new float[] { 00.05f0.1f0.15f0.2f0.25f0.3f0.35f0.4f0.45f0.5f0.55f0.6f0.65f0.7f0.75f0.8f0.85f0.9f0.95f1.0f };
            gradient.Blend = blend;
            // gespiegeltes Artikelteilbild wird mit dem Gradienten überlagert
            grImageBottom.FillRectangle(gradient, new Rectangle(00, ImageTop.Size.Width, ImageTop.Size.Height / 5));
            Bitmap ImageCombination = new Bitmap(ImageTop.Size.Width, ImageTop.Size.Height + ImageTop.Size.Height / 5);
            // Zeilen zwischen Artikelbild und dem gespiegelten Teil weiß einfärben
            Graphics grImageCombination = Graphics.FromImage(ImageCombination);
            SolidBrush BackgroundBrush = new SolidBrush(Color.White);
            grImageCombination.FillRectangle(BackgroundBrush, new Rectangle(00, ImageTop.Size.Width, ImageTop.Size.Height + 10));
            // Artikelbild und gespiegelten Teil in gemeinsames neues Bitmap zeichnen
            using (Graphics g = Graphics.FromImage(ImageCombination)) { g.DrawImage(ImageTop, new Point()); }
            using (Graphics g = Graphics.FromImage(ImageCombination)) { g.DrawImage(ImageBottom, new Point(0, ImageTop.Size.Height+10)); }
            // Neues Artikelbild verzerren, hierfür QuadrilateralDistortion.dll von www.vcskicks.com/image-distortion.php verwendet
            Point topLeft = new Point(00);
            Point topRight = new Point((ImageCombination.Size.Width / 100) * 98, (ImageCombination.Size.Height / 100) * 5);
            Point bottomLeft = new Point(0, ImageCombination.Size.Height);
            Point bottomRight = new Point((ImageCombination.Size.Width/100)*98, (ImageCombination.Size.Height / 100) * 90);
            Bitmap ImageDistort = QuadDistort.Distort(ImageCombination, topLeft, topRight, bottomLeft, bottomRight);
            // Bild in PictureBox darstellen
            pictureBox1.Image = ImageDistort;
            // Rest löschen
            gradient.Dispose();
            ImageTop.Dispose();
            ImageBottom.Dispose();
            ImageCombination.Dispose();
        }
    }
}
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Do 19.08.10 22:31 
Auf Anfrage will ich mal meine ursprüngliche Idee kurz darstellen:

Eine echte perspektivische Projektion, so wie es Direct3D und Co machen, erzeugt man über eine Kamera-Matrix. Wenn wir aber erst einmal komplett im Zweidimensionalen bleiben wollen, besteht die Herausforderung darin, jedem Pixel des verzerrten Rechtecks - im einfachen Coverflow-Fall ein symmetrisches Trapez - ein Pixel des ursprünglichen Bildes zuzuordnen:
Zeichnung
Gemappt werden soll das Pixel am Schnittpunkt. Strecken mit gleichen Farbabschnitten haben jeweils gleiche Teilverhältnisse - genauer gesagt sind das quasi Texturkoordinaten. Der dunkelgrüne Abschnitt zur gesamten Strecke ist u, der dunkelrote v, beide liegen im Intervall [0..1]. Damit müssen wir nur noch für eine gegebene Koordinate im Trapez u und v berechnen.

Nennen wir die Koordinate (x|y) und legen den Ursprung auf die Mitte der linken Seite h1. u ergibt sich nach dem ersten Strahlensatz wie beim Rechteck: u = x / w

Für v ergäbe sich an der linken Kante entsprechend y / h1, wenn der Ursprung in der linken oberen Ecke wäre. Ist er nicht, also machen wir v = (y - h1 / 2) / h1 = y / h1 - 0.5 draus. An der rechten Kante ist die Höhe h2, dazwischen können wir linear interpolieren und ersetzen h1 in der Formel durch (1 - u) * h1 + u * h2. Zusammengefasst:

ausblenden C#-Quelltext
1:
2:
u = x / w
v = y / ((1 - u) * h1 + u * h2) - 0.5

Jetzt beim Suchen der uv-Koordinaten im Bitmap noch eine bilineare Interpolation einbauen und schon bekommt man Anti-Aliasing frei Haus dazu ;) .

PS: Diese einfache Transformation erzeugt wie das verlinkte Projekt ein affines Mapping: With only 2D coordinates, there is no way this is doing perspective correct mapping. Wenn man bei diesem einfachen Weg aber bleiben will und sich noch eine Z-Koordinate dazu-erdichtet, kann man u noch durch diese Formel schicken: en.wikipedia.org/wik...spective_correctness
Einloggen, um Attachments anzusehen!
_________________
>λ=
Net_Hans
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Di 19.10.10 11:53 
Hallo,

ich habe nach der Vorlage in diesem Thema auch ein Testprogramm aufgebaut, welches ein Bild wie oben beschrieben transformiert. Das klappt auch soweit alles wunderbar.
Ich habe leider nur das Problem, das die Berechnung zum fertigen Bild doch recht lange dauert.
Mein Ziel ist es, eine (fast) flüssige Bewegung von einem nicht transformierten zu einem transformierten Bild zu erzeugen.

mein verwendeter Code sieht wie folgt aus:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
            Bitmap ImageTop = new Bitmap("C:\\TEMP\\Unbenannt.bmp");
            this.Text = winkel.ToString();
            Point topLeft = new Point(x1, y1);
            Point topRight = new Point(x2,y2);
            Point bottomLeft = new Point(x3, y3);
            Point bottomRight = new Point(x4, y4);
            Bitmap ImageDistort = QuadDistort.Distort(ImageTop, topLeft, topRight, bottomLeft, bottomRight);
            pictureBox1.Image = ImageDistort;


Die int Variablen x1 .... y4 werden aus Sinuns und Kosinus Berechnungen gewonnen und sind Winkelabhänig.

Kann man das ganze etwas beschleunigen?

Des weiten würde mich interessieren, ob man das ganze auch mit einer Graphic machen kann die man zuvor gezeichnet hat (transparenter Hintergrund)?


Danke für eure Hilfe

mfG Hans