Autor |
Beitrag |
Marc Dirk
      
Beiträge: 41
|
Verfasst: 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 Narses: "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
      
Beiträge: 222
Erhaltene Danke: 16
Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
|
Verfasst: 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 
      
Beiträge: 41
|
Verfasst: 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
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: 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  .
Jetzt warte ich aber erst einmal ab, ob es wirklich das Richtige ist  .
_________________ >λ=
|
|
Marc Dirk 
      
Beiträge: 41
|
Verfasst: 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
      
Beiträge: 665
Erhaltene Danke: 19
win xp, (win vista), win 7
VS 2008 Express Edition, VS 2010 Express Edition, VS 2010 Professionell
|
Verfasst: 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 
      
Beiträge: 41
|
Verfasst: 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

|
|
Marc Dirk 
      
Beiträge: 41
|
Verfasst: Mo 05.04.10 13:13
Hat sich schon mal jemand mit der Viewport3D-Klasse auseinander gesetzt?
Gruß
Marc
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: 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  . Am besten fängst du wahrscheinlich hier an: msdn.microsoft.com/e...ibrary/ms747437.aspx
_________________ >λ=
|
|
ThoMa
      
Beiträge: 46
Erhaltene Danke: 3
|
Verfasst: 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
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 05.04.10 14:59
Affine Transformationen werden hier aber nicht genügen.
_________________ >λ=
|
|
ThoMa
      
Beiträge: 46
Erhaltene Danke: 3
|
Verfasst: 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
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: 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  , aber selbst wenn ich mir den wohl allgemeinsten Konstruktor ansehe, finde ich nur:
_________________ >λ=
|
|
Marc Dirk 
      
Beiträge: 41
|
Verfasst: 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
      
Beiträge: 46
Erhaltene Danke: 3
|
Verfasst: 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 
      
Beiträge: 41
|
Verfasst: 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 
      
Beiträge: 41
|
Verfasst: Di 06.04.10 17:34
So habe ich das Ganze nun gelöst:
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) { return new Bitmap(srcBitmap); }
private void Form1_Paint(object sender, PaintEventArgs e) { Bitmap ImageTop = new Bitmap("C:\\Artikelbild.jpg"); Bitmap ImageBottom = new Bitmap(ImageTop.Size.Width, ImageTop.Size.Height / 5); ImageBottom = Copy(ImageTop); ImageBottom.RotateFlip(RotateFlipType.RotateNoneFlipY); Graphics grImageBottom = Graphics.FromImage(ImageBottom); Color color = Color.Black; Color veryTransparentColor = Color.FromArgb(0, color.R, color.G, color.B); LinearGradientBrush gradient = new LinearGradientBrush(new Rectangle(0, 0, ImageTop.Size.Width, ImageTop.Size.Height / 5), veryTransparentColor, Color.White, 90); Blend blend = new Blend(); blend.Factors = new float[] { 0, 0.05f, 0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.5f, 0.58f, 0.66f, 0.74f, 0.82f, 0.86f, 0.90f, 0.94f, 0.96f, 0.98f, 1.0f }; blend.Positions = new float[] { 0, 0.05f, 0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.5f, 0.55f, 0.6f, 0.65f, 0.7f, 0.75f, 0.8f, 0.85f, 0.9f, 0.95f, 1.0f }; gradient.Blend = blend; grImageBottom.FillRectangle(gradient, new Rectangle(0, 0, ImageTop.Size.Width, ImageTop.Size.Height / 5)); Bitmap ImageCombination = new Bitmap(ImageTop.Size.Width, ImageTop.Size.Height + ImageTop.Size.Height / 5); Graphics grImageCombination = Graphics.FromImage(ImageCombination); SolidBrush BackgroundBrush = new SolidBrush(Color.White); grImageCombination.FillRectangle(BackgroundBrush, new Rectangle(0, 0, ImageTop.Size.Width, ImageTop.Size.Height + 10)); 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)); } Point topLeft = new Point(0, 0); 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); pictureBox1.Image = ImageDistort; gradient.Dispose(); ImageTop.Dispose(); ImageBottom.Dispose(); ImageCombination.Dispose(); } } } |
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: 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:
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:
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
|
Verfasst: 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:
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
|
|
|