Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.
Toon posts:

[C#] Hash van een bitmap

Pagina: 1
Acties:

Verwijderd

Topicstarter
Dag mensen,

Het volgende is het geval:
Op dit moment ben ik een applicatie aan het schrijven die van een deel van een venster een bitmap maakt en weergeeft. En in de toekomst in dat venster kan kijken of er hetzelfde wordt weergegeven. Dit wil ik doen door middel van een hash van een bitmap in een configfile.

Maar nu wil het volgende: dat deel van dat venster moet vergeleken kunnen worden met een waarde uit een configfile. Nu kan ik die bitmap niet los in die configfile dumpen dus moet er een unieke hash van worden gemaakt zodat ik de volgende keer kan controleren of dat deel weer aanwezig is in het venster.

Nu heb ik voor de rest geen flauw idee hoe ik van bijvoorbeeld een bitmap bijvoorbeeld een string kan maken zodat ik deze kan hashen. Google vertelt me ook bijzonder weinig over deze dingen.

Heeft iemand een idee hoe ik een hash van een bitmap kan maken?

Bij voorbaat dank,

  • dominic
  • Registratie: Juli 2000
  • Laatst online: 02-11 11:36

dominic

will code for food

Als je een bitmap wil vergelijken met een andere bitmap op een later moment, lijkt het me dat je de bitmap gewoon als binary opslaat en later weer inleest als bitmap object.

Of is bestandsgrootte van de configfiles een issue?

Edit: zoek anders eens op fingerprinting van bitmaps.

[ Voor 25% gewijzigd door dominic op 22-07-2008 18:21 ]

Download my music on SoundCloud


Verwijderd

Topicstarter
[weg]Sorry ik ben heel erg dom geweest. C# kent de functie plaatje.GetHashCode();

Deze kan op slot, in ieder geval bedankt voor je hulp en volgende keer zoek ik ook eens in VS.NET zelf. :P[/weg]

Deze werkt dus niet, hij geeft elke keer een andere hash terug. Ik zal eens op fingerprinting zoeken. ;)

[ Voor 24% gewijzigd door Verwijderd op 22-07-2008 18:32 ]


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Volgens mij moet het hashen niet zo moeilijk zijn. Een Bitmap laat zich namelijk saven naar een Stream (hier zou je een MemoryStream voor kunnen gebruiken).

Vervolgens kun je met een van de bestaande hashing-implementaties een Stream laten hashen.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Idd wat MrBucket zegt is het makkelijkst. Echter vraag ik me af of het plaatje wat je krijgt echt exact hetzelfde is. Je hebt het over een venster, dus weet je zeker dat deze exact ( Dus elke pixel ) precies hetzelfde is. Als er namenlijk maar 1 pixel maar 1 bit anders is krijg je al een compleet andere hash.

Je zou dan als oplossing inderdaad kunnen kijken naar fingerprinting, of je zou gewoon je complete originele image op kunnen slaan en het verschil tussen de twee plaatjes kunnen berekenen. Als het verschil dan klein genoeg is, heb je een match

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
rwb schreef op dinsdag 22 juli 2008 @ 19:42:
Idd wat MrBucket zegt is het makkelijkst. Echter vraag ik me af of het plaatje wat je krijgt echt exact hetzelfde is. Je hebt het over een venster, dus weet je zeker dat deze exact ( Dus elke pixel ) precies hetzelfde is. Als er namenlijk maar 1 pixel maar 1 bit anders is krijg je al een compleet andere hash.
Dat is nu juist de kracht van hashing ;)
Of je het ook wil is vers 2 natuurlijk.
Je zou dan als oplossing inderdaad kunnen kijken naar fingerprinting, of je zou gewoon je complete originele image op kunnen slaan en het verschil tussen de twee plaatjes kunnen berekenen. Als het verschil dan klein genoeg is, heb je een match
Maar ja, wat is dan een "klein genoeg verschil"? 1 pixel, 10 pixels, 50 pixels? En moeten de verschillen dan dicht bij elkaar liggen, of...? Het wordt behoorlijk lastig om een duidelijke fingerprint te verzinnen, denk ik.

Als de hash alleen bedoelt is om te bepalen of er een nieuwe versie van de screenshot opgeslagen moet worden of dat de oude kan worden hergebruikt (aanname van mijn kant), dan lijkt het me niet zo'n probleem om bij 1 pixel verschil gewoon een nieuwe versie op te slaan?
--edit: als je tenminste geen geanimeerde tray-icons en/of knipperende cursors opslaat als onderdeel van je image... :X

[ Voor 4% gewijzigd door MrBucket op 22-07-2008 19:56 ]


Verwijderd

Topicstarter
Nou ondertussen ben ik eruit en aangezien ik dit topic geopend heb vind ik het ook nodig om de oplossing even erbij te zetten:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
        public uint getHash(Bitmap plaatje)
        {
            
            ImageConverter ic = new ImageConverter(); //Maak een nieuwe imageconverter
            byte[] image = new byte[1]; //Maak een nieuwe byte aan
            image = (byte[])ic.ConvertTo(plaatje, image.GetType()); //Zet het plaatje om in bytes

            SHA256Managed sha = new SHA256Managed();
            byte[] bhash = sha.ComputeHash(image); //Maak een hash van het plaatje in bytes
            uint hash = BitConverter.ToUInt32(bhash, 0); //Maak van de bytes een unsigned integer
            
            return hash;
        }


Deze werkt wel. :)

Bedankt voor de hulp en er kan een slotje op. :)

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Je slaat een 256-bit grote hash nu op in een 32-bit integer; dat lijkt me niet helemaal de bedoeling.

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
PrisonerOfPain schreef op woensdag 23 juli 2008 @ 03:29:
Je slaat een 256-bit grote hash nu op in een 32-bit integer; dat lijkt me niet helemaal de bedoeling.
Ach, ook een manier om te bepalen of een gedeelte gewijzigd is.

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 00:56
Plus, je maakt nutteloos een byte- array van grootte 1 aan, om die vervolgens te overschrijven met de image- data, dit volstaat, in plaats van regel 5 en 6:
C#:
1
            byte[] image = (byte[])ic.ConvertTo(plaatje, image.GetType()); //Zet het plaatje om in bytes


Je moet gewoon die byte- array returnen en die gebruiken om te kijken of het plaatje veranderd is.

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • Mac_Cain13
  • Registratie: Juni 2003
  • Laatst online: 13-10 20:39
Gomez12 schreef op woensdag 23 juli 2008 @ 07:29:
[...]

Ach, ook een manier om te bepalen of een gedeelte gewijzigd is.
Euh, nee niet dus. Een stukje van een SHA1 has zegt namelijk niets. Al helemaal niet of een deel van je afbeelding verandert is. Als je alleen de eerste 32-bit vergelijkt weet je alleen zeker dat hij verschillend is óf dat de hash misschien hetzelfde zou kunnen zijn. Meer niet, hierbij kunnen de plaatjes echt totaal verschillend zijn.

Moraal van het verhaal. Als je een hash maakt zet hem dan ook volledig in een variabele en niet voor een stukje. :P

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Wat Gomez12 denk ik bedoelt is dat je als je alleen de eerste 32 bits vergelijkt, je ook de wijziging waarschijnlijk wel detecteert. Je hebt alleen meer kans op collisions.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • HawVer
  • Registratie: Februari 2002
  • Laatst online: 22:54
Waarom maak je niet gebruik van een checksum?

http://hawvie.deviantart.com/


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 21:28
Ik zou niet wagen op de GetHashCode, volgens mij is dit een referenceequals variant.

Hier is iemand die jouw probleem al gerealiseerd heeft:

http://www.codeproject.com/KB/GDI-plus/comparingimages.aspx

Ik zou alleen een break statement willen toevoegen bij een mismatch


code:
1
2
3
4
5
6
7
8
9
for (int i = 0; i < hash1.Length && i < hash2.Length 
                                  && cr == CompareResult.ciCompareOk; i++)
                {
                    if (hash1[i] != hash2[i])
                    {
                        cr = CompareResult.ciPixelMismatch;
                        break;
                    }
                }


suc6!

[ Voor 51% gewijzigd door DrDelete op 23-07-2008 12:40 ]


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
HawVer schreef op woensdag 23 juli 2008 @ 12:32:
Waarom maak je niet gebruik van een checksum?
SHA256Managed sha = new SHA256Managed();

Natuurlijk is een dergelijke cryptografisch-sterke hash een beetje overkill, maar het werkt minstens net zo goed als een CRC32 checksum (wat ook gewoon een hash is). Met een CRC32 check zal (theoretisch) je bij 1 op de 2^32 plaatjes een collision hebben, met SHA256 bij 1 op de 2^256 plaatjes.
DrDelete schreef op woensdag 23 juli 2008 @ 12:37:
Ik zou niet wagen op de GetHashCode, volgens mij is dit een referenceequals variant.

Hier is iemand die jouw probleem al gerealiseerd heeft:
Op exact dezelfde manier, door het bouwen van een SHA256 has van de image bytes.

[ Voor 35% gewijzigd door Hydra op 23-07-2008 14:40 ]

https://niels.nu

Pagina: 1