ich habe bei meiner Hauptanwendung als Zielplattform "Any CPU" eingestellt. Diese wird also auf 32Bit-System als 32Bit und auf 64Bit-System als 64Bit ausgeführt.
Meine referenzierte Klassenbibliothek muss leider unter 32 Bit laufen. Diese greift auf meinen installierten Canon RAW Codex zu, welcher leider nur in 32Bit existiert.
Ist es möglich, mit meiner 64Bit-Anwendung auf meine 32Bit-Klassenbibliothek zuzugreifen?
Ich weiß, ich könnte meine Anwendung auch insgesamt auf 32Bit umstellen, würde aber aus verschiedenen Gründen (bsp. Perfomance) gerne bei 64Bit (bzw. Any CPU) bleiben.
meine Anwendung soll ein Bild anzeigen können, welches sich mit einem Schieberegler zoomen lässt. Das klappt alles. Ich benutze dafür eine Viewbox und ein ScaleTransform.
Das Problem ist allerdings folgendes: wenn ich das Bild so zoome, dass es größer als die Viewbox wird, tritt das Bild über die Viewbox hinaus.
Etwas schwer zu erklären - ich habe mal ein Beispielprojekt angehangen.
Ich könnte Controls (z.B. Grids) um die Viewbox herum platzieren, welche im Vordergrund sind. Das klappt auch. Allerdings benutze ich in meiner Hauptanwendung den Glass-Effekt von Windows Vista/7 und muss die Oberfläche deshalb an der entsprechenden Stelle von Controls freihalten.
Habt ihr vielleicht eine Lösung, wie ich das heraustreten des Bildes verhindern kann? Vielen Dank.
So, hier kommt die Lösung :-) Nachdem ich tagelang gesucht und gesucht habe.. die Lösung ist so verdammt einfach. Folgender Quellcode-Schnispel sollte Erklärung genug sein:
public BitmapSource Execute(BitmapSource bitmap)
{
double newWidth = bitmap.PixelWidth + config.Thickness * 2;
double newHeight = bitmap.PixelHeight + config.Thickness * 2;
RenderTargetBitmap renderTarget = new RenderTargetBitmap(
(int)newWidth,
(int)newHeight,
bitmap.DpiX,
bitmap.DpiY,
PixelFormats.Default);
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
Rect imageRect = new Rect(config.Thickness, config.Thickness, bitmap.PixelWidth, bitmap.PixelHeight);
Pen pen = new Pen(Brushes.Black, config.Thickness);
using (drawingContext)
{
drawingContext.DrawRectangle(Brushes.Black, pen, new Rect(0, 0, newWidth, newHeight));
drawingContext.DrawImage(bitmap, imageRect);
}
renderTarget.Render(drawingVisual);
return renderTarget as BitmapSource;
}
Das ist interessant.. ich hatte vorher die Postion des ImageControls auf der Oberfläche vorher mit Margins festgelegt und Stretch auf "Uniform" gestellt.
Nun habe ich die Margins entfernt und Stretch auf "None" gestellt.
<Image Name="imageControl" Stretch="None" />
Ergebnis: Das gespeicherte Bild ist nun nicht schwarz - jetzt ist es hellblau. Hä? :-)
this.imageControl.Source = new BitmapImage(new Uri(@"C:\test\go.jpg"));
this.imageControl.Effect = new MyEffect(@"C:\test\ps\ZoomBlur.ps");
Das Bild blieb auf der Oberfläche unverändert. Komisch - ich hatte im Kopf, dass dieser Filter funktioniert. Nun habe ich einen anderen genommen, welcher mit den obigen beiden Zeilen funktioniert (InvertColor). Wenn ich das Bild allerdings speichere, ist dies komplett schwarz.
Irgendwie funktioniert das mit dem Rendern wohl nicht.
public class MyEffect : ShaderEffect
{
public MyEffect(string file)
{
this.PixelShader = new PixelShader()
{
UriSource = new Uri(file, UriKind.Absolute)
};
}
}
Irgendetwas mache ich falsch, denn leider komme ich zu dem Ergebnis wie im Anhang.
Achso - ich dachte, dass würde nur funktionieren, wenn das ImageControl auf der Oberfläche sichtbar ist. Also wird ja nicht direkt Screenshot gemacht. Hast du vielleicht schon ein funktionierendes Beispiel dazu?
Ich hätte den HLSL-Code nur in c# umgewandelt, wenn ich die PixelShader nicht benutzen würde. ;)
Ganz genau das ist das schöne an den PixelShadern: Es gibt massenhaft Beispiele, also könnte ich sehr viele Filter anbieten. Ganz abgesehen von den anderen Problemen, ist es überhaupt möglich auf ein ImageControl mehrere PixelShader anzuwenden? Dazu noch eine Frage: Wenn die das Bild auf der Oberfläche anzeige um ein Screenshot zu machen - dann habe ich doch (alleine von der Größe her) einen immensen Qualitätsverlust gegenüber dem originalen, oder? In den meisten Fällen werde ich das ImageControl nach nicht so groß wie das originale Bild machen können, ganz geschweige davon, dass das der Benutzer ja nicht sehen soll.
Mit C habe ich leider noch nie gearbeitet. Wenn das mit den PixelShadern nicht funktioniert werde ich wohl wirklich versuchen, den HLSL-Code in c#-Code umzuwandeln.
ich bin gerade dran, ein Programm für eine Bild-Stapelverarbeitung zu entwickeln. Soll heißen: Der Benutzer kann eine beliebige Anzahl von Bildern auswählen und diese mit beliebig vielen Bearbeitungsschritten bearbeiten (bsp. Rahmen setzen, Schrift einfügen, Größe ändern, Drehen, usw.)
Nun möchte ich Filter einbauen. Das heißt zum Beispiel eine Schwarz/Weiss-Konvertierung, Sepia oder die Veränderung des Kontrastes. Dazu gibt es endlos viele Möglichkeiten.
Mit dem .NET Framework 3.5 kamen die PixelShader. Leider können diese wohl nicht auf ein BitmapSource angewendet werden. Ich habe im Internet nirgends eine Lösung gefunden.
Ein weitere Möglichkeit wäre die Verarbeitung auf Pixelebene. Allerdings ist diese erstens langsam und zweitens kompliziert - ich wüsste beispielsweise nicht wie ich dann den Kontrast erhöhen könnte, ganz geschweige von vielen anderen Szenarien.
Bei System.Drawing gibt es die ColorMatrix, mit der man viel machen konnte. Leider scheint diese in WPF zu fehlen. Und jedes mal ein BitmapSource in ein Bitmap umwandeln und wieder zurück wird sehr viel Zeit beanspruchen.
Nun stehe ich da und finde keine richtige Lösung. PixelShader fände ich sehr interessant. Erstens sind diese sehr schnell und zweitens gibt es einige Beispiele. Nur doof, dass ich sie anscheinend technisch nicht verwenden kann.
Habt ihr eventuell eine Lösung für mich - wie ich die Bilder möglichst schnell verarbeiten kann und wozu es auch einige Beispiele gibt? Vielen Dank für eure Hilfe.
Vielen Dank für den Link. Ich werde mir das Tool heute Abend zu Hause mal anschauen.
Das mit man mit den Shaders sehr viel machen kann, habe ich schon bemerkt :-) Ich habe nur nichts gefunden, wie ich diese auf ein BitmapImage anwenden kann. Bei den Beispielen im Internet sind diese immer direkt an ein Image-Control gebunden, was mir an dieser Stelle ja nichts bringt.
Ich könnte ein PlugIn für Filter und ein PlugIn für Sonstiges (also bsp. Rahmen) anbieten. Das klingt gut :)
WPF kann ich ja trotzdem weiter benutzen, eben nur nicht für die eigentliche Bearbeitung. Diese könnte ich dann mit System.Drawing machen.
Auf die Pixelshader bin ich auch gestoßen, allerdings habe ich dort sehr wenige Tutorials gefunden, wie man diese genau anwendet. Für Filter wären diese aufgrund ihrer hohen Geschwindigkeit eigentlich sehr interessant.
Ich weiß, dass das mit System.Drawing alles relativ einfach funktioniert. Ich habe die einzelnen Bearbeitungsschritte damit ja alle schon mal so ähnlich gemacht.
Warum macht das niemand mit WPF? Wenn ich mit System.Drawing mehr Vorteile habe, kann ich das auch damit machen. Ich dachte nur, dass mir WPF (bzw. .NET 4.0) mehr Funktionalität und Performance bietet.
Das Vorschaubild soll erst am Ende angezeigt werden. Es können sich beliebig viele PlugIns einschalten und einen Bearbeitungsschritt zur Verfügung stellen. Ist die Frage, ob ich den PlugIns eine System.Drawing.Bitmap oder ein System.Windows.Media.Imaging.BitmapImage übergebe.
Eventuell könnten die einzelnen Bearbeitungsschritte mit einer Bitmap arbeiten und ganz am Ende wird diese zur Anzeige in ein BitmapImage umwandelt.
Das Programm soll viele einzelne Bildbearbeitungsschritte auf einen Bilderstapel machen. Das heißt, es geht in einer Schleife alle Bilder durch und wendet die einzelnen Bearbeitungsschritte (z.B. Rahmen setzen, Größe ändern, S/W, ...) an. Deshalb versuche ich sehr auf Geschwindigkeit zu achten, auch wegen der Erstellung eines Vorschaubildes.
Schade ist, dass es im Internet kaum Beispiele gibt, wie man BitmapImages bearbeiten kann.
Ich weiß, wie ich ein BitmapImage einem Image zuweise :-)
Ein Image ist doch ein Control, was eigentlich nur zum Anzeigen auf einer Oberfläche gedacht ist, oder?
Und damit hätte ich ja immernoch das Problem, einen Rahmen ums Bild zu setzen. Am liebsten würde ich das ohne die Verwendung von System.Drawing machen, was glaube ich sinnvoller ist.
ich hatte vor einer Weile mal ein kleines Bildbearbeitungsprogramm in .NET 2.0 geschrieben. Nun bin ich gerade dran, dieses in .NET 4.0 - in einer WPF-Anwendung - zu entwickeln.
Es gibt eine Methode, die ein BitmapImage übergeben bekommt und auch ein solches zurückliefert. In der Methode soll in (!) dem BitmapImage ein Rahmen mit bestimmter Farbe/Größe gesetzt werden.
Weiß jemand, wie ich das am besten lösen könnte? Im Internet finde ich leider nichts dazu.
Vielen Dank für eure Hilfe.
ich bin gerade dabei ein kleines Bildbearbeitungsprogramm zu entwickeln, welches sich durch AddIns erweitern lassen soll. Hier sollen den AddIns nacheinander das entsprechende BitmapImage übergeben werden, welche dieses dann bearbeitet können. (Stapelprozess)
Ich benutze System.AddIn. Das Problem: Ich kann das BitmapImage leider nicht übergeben, dass dieses nicht serialisierbar ist. (Es wird ein Fehler geworfen)
Wegen der Performance wäre es sehr schlecht, wenn jedes AddIn das Bild öffnen, bearbeiten und wieder speichern müsste.
Gibt es irgendwie eine Möglichkeit, das BitmapImage zu übergeben?
ich habe ein Problem mit dem BackgroundWorker und das Laden eines BitmapImages von der URL. Über folgenden Code lade ich das Bild in der DoWork-Methode des BackroundWorkers herunter:
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.None;
image.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
image.UriSource = new Uri(url);
image.EndInit();
//image.Freeze();
e.Result = image;
Das BItmapImage wird über e.Result an das Event RunWorkerCompleted übergeben. Wenn ich dann das BitmapImage einem Image-Control übergebe, kommt folgender Fehler:
Zitat
Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, da sich das Objekt im Besitz eines anderen Threads befindet.
Im Internet gibt es ein paar Antworten auf dieses Problem, die sagen, man solle nach dem image.EndInit() ein image.Freeze() aufrufen, doch dann kommt bei mir folgender Fehler:
Zitat
Dieses Freezable-Objekt kann nicht fixiert werden.
Habt ihr eine Idee, was ich evtl. falsch mache? Danke!
in jedem AddOn gibt's eine Klasse für die Datenhaltung. Dieser Klasse ist von IAddOnData abgeleitet. Contract, die Adapters und Views implementieren dieses Interface und machen es nach außen zugänglich. Nun versuche ich den Inhalt der Datenhaltungs-Klassen zu serialisieren: