Laden...

Bilder vergleichen ???Hash???

Erstellt von lorddoener vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.307 Views
lorddoener Themenstarter:in
14 Beiträge seit 2009
vor 15 Jahren
Bilder vergleichen ???Hash???

Hallo!

Bin neu im Forum und hoffe, dass ich den richtigen Themenbereich erwischt habe.

Zum Problem:
Ich habe ein kleines "Zeichenprogramm" geschrieben, dass eine bmp Datei öffnet, in der man dann malen kann und die man dann speichern kann, ...
Tja, alles klappt, aber ich würde gerne mit dem Button "Neu" im Menü eine bmp Datei erstellen und:
Vorher überprüfen, ob die Datei (der Pfad und Dateiname ist in "filename" gespeichert) irgendwelche Änderungen aufweist. Wenn ja, dann fragen ob speichern oder verwerfen, wenn nein, dann einfach neue bitmap erstellen.
Ich habe gelesen, dass man da die Datei hashen kann und dann beide vergleichen, aber stimmt das auch?
Wenn ja, wie macht man das?

MFG lorddoener

Wer Rechtschreibfeela findet darf sie behalten!

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo lorddoener,

klar, kannst du machen. Siehe MD5-Klasse in der :rtfm: Doku.

herbivore

5.742 Beiträge seit 2007
vor 15 Jahren

Hallo lorddoener,

herzlich willkommen hier im Forum!!

Warum denn so kompliziert?
Verwende einfach eine boolsche Variable, die bei Änderungen des Users ihren Wert ändert.

Oder möchtest du erreichen, dass du erfährst wenn externe Programme die Datei ändern? Dann wird es vermutlich reichen, das Datum der letzten Änderung auszuwerten.

Oder habe ich etwas falsch verstanden?

lorddoener Themenstarter:in
14 Beiträge seit 2009
vor 15 Jahren

Die Idee mit der Boolschen Variable ist nicht schlecht.
Aber dann muss ich ja bei jeder Zeichenoperation oder beim setzen eines Filters, ... die Variable setzen, oder gibts da ne andere Möglichkeit?

Wenn andere Programme die Datei ändern ist mir das egal.
Geht ja nur um Bilder und da hab ich ja auch nicht immer Paint und Photoshop offen 😉

Wenn ich dann viele Operationen hab ist das mit dem hashen wahrscheinlich besser, aber wenn das Bild groß ist bringt das dann immer noch was?

Das mit der letzten Änderung wäre ne Überlegung wert, da sind aber die anderen Methoden wahrscheinlich zielführender?!

MFG lorddoener

Wer Rechtschreibfeela findet darf sie behalten!

84 Beiträge seit 2007
vor 15 Jahren

Das Vorgehen ist eigentlich vom Prinzip her immer gleich:

Der Zweck eines Events ist es, dich über eine Änderung oder einen bestimmten Vorgang zu informieren. In deinem Fall willst du informiert werden, wenn auf deinen Bitmap eine beliebige Zeichenoperation angewendet wird.
Es ist dir aber egal, welche Operation da genau ausgeführt wird, denn du willst anschließend ja nur das Flag "HatUngespeicherteÄnderungen" auf true setzen.

Deshalb ist es zu feingranular, bei jeder Zeichenoperation das Flag zu setzen, du benötigst einen untergeordneten Event, der bei allen Zeichenoperation gefeuert wird. Das könnte in deinem Fall z.B. ein Event "BitmapChanged" sein, den der Setter einer Propertie auslöst:


// Bitmap
Bitmap currentImage;

// Bitmap Propertie
Bitmap CurrentImage
{
get
{
     BitmapChanged();
     return currentImage
}

set
{
currentImage = value;
}

// Event
event EventHandler BitmapChanged;


(Code etwas vereinfacht, es fehlen die EventArgs etc.)

Bei jedem Schreibzugriff auf dein aktuelles Bitmap - egal ob durch Pinsel, Weichzeichner oder sonstwas - wird der "BitmapChanged"-Event gefeuert - diesen kannst du abonnieren und bei Eintritt z.B. das Flag "HasPendingChanges" auf true setzen.

Gruß,
Razer

84 Beiträge seit 2007
vor 15 Jahren

Ich habe gelesen, dass man da die Datei hashen kann und dann beide vergleichen, aber stimmt das auch?

Ich glaube die Hashes zu vergleichen ist so ziemlich der aufwendigste Weg um die von dir gewünschte Funktionalität zu erreichen 😉

Gerade bei Bitmaps kommen bei höheren Auflösungen vergleichsweise hohe Datenmengen auf, sodass jedesmal die komplette Datei einzulesen wäre. Da schießt du dann eindeutig mit Kanonen auf Spatzen.

Gruß,
Razer

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Razer,

naja, es war ja schon spät. 😃

Auch wenn dein Code vereinfacht ist, so ist es doch schlicht falsch, dass der Event im Getter ausgelöst wird. Mal abgesehen davon, dass du die ganze Zeit im Text über Zeichenoperationen schreibst, die also den Inhalt des Bitmap-Objekts ändern und als Codebeispiel das Feuern des Events beim Austauschen des Bitmap-Objekts als ganzes zeigst. Das passt nicht so ganz.

Hier noch ein zwei Punkte, die vermutlich durch die Vereinfachung entstanden sind, aber m.E. ein falschen Eindruck geben. Ein Event sollte nie direkt ausgelöst werden, sondern sollte vor dem Auslösen immer auf != null abgefragt werden. Dazu schreibt man sich per Konvention/Empfehlung immer eine Methode, die wie das Event heißt, aber ein On vorangestellt bekommt. Hier also OnBitmapChanged. Außerdem sollte man ein solches Events nur auslösen, wenn auch tatsächlich eine Änderung erfolgt ist, also in dem Beispiel nur wenn currentImage != value.

Die ganze Geschichte gibt es in [FAQ] Eigenen Event definieren.

Eine Frage bleibt noch: Lohnt sich der Aufwand? Denn an der Stelle, wo man den Event auslösen würde, könnte man auch einfach direkt das Flag setzen. 😃 Es liegt ja hier kein Grund vor, das Setzen des Flags durch ein Events zu entkoppeln.

Und eins muss man natürlich sowieso sagen. Das Flag gibt so nur an, ob mindestens eine ändernde Operation durchgeführt wurde. Das sagt nicht, dass die Bitmap nach den ganzen Operationen auch tatsächlich einen anderen Inhalt hat als zu Anfang. Denn wenn ich z.B. auf einer komplett weißen Bitmap erst ein rotes Objekt zeichne, dieses aber wieder komplett weiß übermale, habe ich zwei andernde Operationen durchgeführt, wodurch das Flag auf "geändert" steht, obwohl die Bitmap jetzt den gleichen Inhalt hat, wie zu Anfang. Das mag zwar wie Haarspalterei klingen, kommt aber durchaus vor und ich finde es insbesondere bei Textverarbeitungsprogrammen wirklich nervig, wenn ich in einem Text, den ich längere Zeit offen hatte, versehentlich ein Zeichen eingefügt habe, das ich sofort wieder lösche und trotzdem beim Abspeichern gefragt werde, ob ich die (nicht vorhandenen) Änderungen speichern möchte. Ich muss dann nämlich erst darüber nachdenken, ob ich nicht doch noch eine andere relevante Änderung oder nur die versehentliche gemacht habe. Dazu haben ich ja eigentlich einen Computer, damit ich mir nicht mehr selbst alles merken muss.

Gerade bei Bitmaps kommen bei höheren Auflösungen vergleichsweise hohe Datenmengen auf, sodass jedesmal die komplette Datei einzulesen wäre. Da schießt du dann eindeutig mit Kanonen auf Spatzen.

Nein, durch den Hash würde man sich das ja gerade sparen. Man hätte also den einen einen Hash immer parat und müsste nur den Hash von dem potentiell geänderten Objekt berechnen. Und das liegt ja im Speicher, weshalb die Berechnung auch bei großen Bitmaps entsprechend schnell durchführbar wäre.

herbivore

lorddoener Themenstarter:in
14 Beiträge seit 2009
vor 15 Jahren

Also wäre die Methode mit dem hashen doch sehr praktisch, denn wenn man ein rechteck zeichnet und es wieder ohne einen pixel zu übersehen übermalt dann stimmen die hashes (schreibt man so?) ja wieder überein.

Wer Rechtschreibfeela findet darf sie behalten!

946 Beiträge seit 2008
vor 15 Jahren

Die Idee mit der Boolschen Variable ist nicht schlecht.
Aber dann muss ich ja bei jeder Zeichenoperation oder beim setzen eines Filters, ... die Variable setzen, oder gibts da ne andere Möglichkeit?
[...]
Wenn ich dann viele Operationen hab ist das mit dem hashen wahrscheinlich besser

Wo ist das Problem? Eine bool-Variable von true auf true zu setzen ist wohl nicht besonders zeitaufwändig.

Wenn du unbedingt willst, kannst du den event entfernen und beim Speichern wieder aktivieren.

Das Hashen ist ja etwas zu aufwändig und vor allem auf einem Punkt konzentriert.

Ich glaube aber, die Variante mit dem bool ist auch in der Summe kürzer und die meisten Programme machen das so.
Du machst dir vermutlich unnötig Gedanken.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo See Sharp,

Das Hashen ist ja etwas zu aufwändig ...

das ist eine reine Bewertungsfrage. Es ist sicher zeitaufwändiger als das Setzen eines bool. Aber dass es zu aufwändig wäre, kann man so pauschal nicht sagen. Zumal der Code relativ kurz ist ...

Ich glaube aber, die Variante mit dem bool ist auch in der Summe kürzer ...

... und nicht zwangsweise länger als an möglicherweise vielen Stellen einen bool zu setzen.

... und die meisten Programme machen das so.

Ja, leider. Ich habe ja schon oben geschrieben, dass mich das nervt.

... und vor allem auf einem Punkt konzentriert.

Das ist ja wohl ein klarer Vorteil!

Du machst dir vermutlich unnötig Gedanken.

Die Gedanken machen ja wohl eher du und ich uns. 😃 lorddoener wollte von Anfang an nur wissen, ob und wie das mit dem Hash geht.

herbivore

84 Beiträge seit 2007
vor 15 Jahren

naja, es war ja schon spät. 🙂

jop 😁

Auch wenn dein Code vereinfacht ist, so ist es doch schlicht falsch, dass der Event im Getter ausgelöst wird. Mal abgesehen davon, dass du die ganze Zeit im Text über Zeichenoperationen schreibst, die also den Inhalt des Bitmap-Objekts ändern und als Codebeispiel das Feuern des Events beim Austauschen des Bitmap-Objekts als ganzes zeigst. Das passt nicht so ganz.

Wenn ich das Bitmap hinter einer Propertie "verstecke" impliziert dass ja aber nicht, dass ich das Bitmap ab sofort immer nur als Ganzes ersetze.
Beim Zugriff via SetPixel etwa ist dies eigentlich nicht der Fall.
Die von den Designern generierten Klassen feuern ihre Änderungs-Events auch in den Settern.

Ein Event sollte nie direkt ausgelöst werden, sondern sollte vor dem Auslösen immer auf != null abgefragt werden.

ja, der Code war halt (zu) skizzenhaft.

Eine Frage bleibt noch: Lohnt sich der Aufwand? Denn an der Stelle, wo man den Event auslösen würde, könnte man auch einfach direkt das Flag setzen. 🙂 Es liegt ja hier kein Grund vor, das Setzen des Flags durch ein Events zu entkoppeln.

Wenn die Überprüfung die einzige Aufgabe ist, besteht dazu eigentlich keine Notwendigkeit, stimmt. Müssen aber noch weitere Ausgaben ausgeführt werden, fände ich das Auslagern weniger bedenklich.

Gerade bei Bitmaps kommen bei höheren Auflösungen vergleichsweise hohe Datenmengen auf, sodass jedesmal die komplette Datei einzulesen wäre. Da schießt du dann eindeutig mit Kanonen auf Spatzen.
Nein, durch den Hash würde man sich das ja gerade sparen. Man hätte also den einen einen Hash immer parat und müsste nur den Hash von dem potentiell geänderten Objekt berechnen. Und das liegt ja im Speicher, weshalb die Berechnung auch bei großen Bitmaps entsprechend schnell durchführbar wäre.

war definitiv zu spät 8o

=> @lorddoener ich drehe meinen Standpunkt um 180 Grad, und bin auch dafür dass du deine Bitmaps hashed 😉

lorddoener Themenstarter:in
14 Beiträge seit 2009
vor 15 Jahren

ok, wird auch einfacher sein, weil ich dann meinen code nur (wenig) ändern muss.
Danke für eure Tipps und Antworten!

MFG lorddoener

Wer Rechtschreibfeela findet darf sie behalten!