Mein code : Daten in einem png Bild verstecken

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Neutrino
Beiträge: 10
Registriert: 15.02.2006 12:29
Kontaktdaten:

Mein code : Daten in einem png Bild verstecken

Beitrag von Neutrino »

Habe ein Programm geschrieben das einen string in zeichen zerlegt und dann die zeichen in RGB werte convertiert und in ein Bild schreibt und umgekehrt. Weiß im moment auch nicht was für einen Sinn das hat aber wollte es einfach mal ausprobieren. Vieleicht könnte man es ja so umschreiben das es ein Datenbild gibt und ein Original Bild und das dann beide Bilder verglichen werden und somit die Daten wieder extracted werden können, man könnte so z.B. in einem Bild geheime daten verstecken welche dann nur abgerufen werden können wenn das Original Bild vorhanden ist, jeder andere würde dann halt nur ein Bild von einer Landschafft oder ähnlich sehen.

Code: Alles auswählen


;this code is GPL
;codet by Neutrino

UsePNGImageDecoder()
UsePNGImageEncoder()

Declare ConvertCharToRGB(char.s)
Declare InjectStringToImage(FileName.s,StringToInject.s)
Declare.s ExtractStringFromImage(filename.s)
Declare CreateEmptyDataImage(filename.s)
Declare.s ConvertRGBToChar(rgbnumber)

If CreateEmptyDataImage("c:\test.png")
  If InjectStringToImage("c:\test.png","hello world")
    x$ = ExtractStringFromImage("c:\test.png")
    ;Debug x$
    If x$
      MessageRequester("Extracted String: ",x$,0)
    Else
      ;error
      MessageRequester("Error","Extract String")
    EndIf
  Else
    MessageRequester("Error","Inject String")
  EndIf
Else
  MessageRequester("Error","create image",0)
EndIf

Procedure ConvertCharToRGB(char.s)
  Select char
    Case "a" ;RGB(23,23,1)
      ProcedureReturn 71447
    Case "b"  ;RGB(23,23,2)
      ProcedureReturn 136983
    Case "c"  ;RGB(23,23,3)
      ProcedureReturn 202519
    Case "d"  ;RGB(23,23,4)
      ProcedureReturn 268055
    Case "e"  ;RGB(23,23,5)
      ProcedureReturn 333591
    Case "f"  ;RGB(23,23,6)
      ProcedureReturn 399127
    Case "g"  ;RGB(23,23,7)
      ProcedureReturn 464663
    Case "h"  ;RGB(23,23,8)
      ProcedureReturn 530199
    Case "i"  ;RGB(23,23,9)
      ProcedureReturn 595735
    Case "j"  ;RGB(23,23,10)
      ProcedureReturn 661271
    Case "k"  ;RGB(23,23,11)
      ProcedureReturn 726807
    Case "l"  ;RGB(23,23,12)
      ProcedureReturn 792343
    Case "m"  ;RGB(23,23,13)
      ProcedureReturn 857879
    Case "n"  ;RGB(23,23,14)
      ProcedureReturn 923415
    Case "o"  ;RGB(23,23,15)
      ProcedureReturn 988951
    Case "p"  ;RGB(23,23,16)
      ProcedureReturn 1054487
    Case "q"  ;RGB(23,23,17)
      ProcedureReturn 1120023
    Case "r"  ;RGB(23,23,18)
      ProcedureReturn 1185559
    Case "s"  ;RGB(23,23,19)
      ProcedureReturn 1251095
    Case "t"  ;RGB(23,23,20)
      ProcedureReturn 1316631
    Case "u"  ;RGB(23,23,21)
      ProcedureReturn 1382167
    Case "v"  ;RGB(23,23,22)
      ProcedureReturn 1447703
    Case "w"  ;RGB(23,23,23) / yeah goal 
      ProcedureReturn 1513239
    Case "x"  ;RGB(23,23,24)
      ProcedureReturn 1578775
    Case "y"  ;RGB(23,23,25)
      ProcedureReturn 1644311
    Case "z"  ;RGB(23,23,26)
      ProcedureReturn 1709847
    Case " "  ;RGB(23,23,27)
      ProcedureReturn 1775383
    Case Chr(4);RGB(23,23,28) / end of string
      ProcedureReturn 1840919  
  EndSelect
EndProcedure

Procedure.s ConvertRGBToChar(rgbnumber)
  Select rgbnumber
    Case 71447 ;RGB(23,23,1)
      ProcedureReturn "a"
    Case 136983  ;RGB(23,23,2)
      ProcedureReturn "b" 
    Case 202519  ;RGB(23,23,3)
      ProcedureReturn "c"
    Case 268055  ;RGB(23,23,4)
      ProcedureReturn "d"
    Case 333591  ;RGB(23,23,5)
      ProcedureReturn "e"
    Case 399127  ;RGB(23,23,6)
      ProcedureReturn "f"
    Case 464663  ;RGB(23,23,7)
      ProcedureReturn "g"
    Case 530199  ;RGB(23,23,8)
      ProcedureReturn "h"
    Case 595735  ;RGB(23,23,9)
      ProcedureReturn "i" 
    Case 661271  ;RGB(23,23,10)
      ProcedureReturn "j"
    Case 726807  ;RGB(23,23,11)
      ProcedureReturn "k"
    Case 792343  ;RGB(23,23,12)
      ProcedureReturn "l" 
    Case 857879  ;RGB(23,23,13)
      ProcedureReturn "m" 
    Case 923415  ;RGB(23,23,14)
      ProcedureReturn "n" 
    Case 988951  ;RGB(23,23,15)
      ProcedureReturn "o" 
    Case 1054487  ;RGB(23,23,16)
      ProcedureReturn "p"
    Case 1120023  ;RGB(23,23,17)
      ProcedureReturn "q"
    Case 1185559  ;RGB(23,23,18)
      ProcedureReturn "r"
    Case 1251095  ;RGB(23,23,19)
      ProcedureReturn "s"
    Case 1316631  ;RGB(23,23,20)
      ProcedureReturn "t" 
    Case 1382167  ;RGB(23,23,21)
      ProcedureReturn "u"
    Case 1447703  ;RGB(23,23,22)
      ProcedureReturn "v"
    Case 1513239  ;RGB(23,23,23) / yeah goal 
      ProcedureReturn "w" 
    Case 1578775  ;RGB(23,23,24)
      ProcedureReturn "x" 
    Case 1644311  ;RGB(23,23,25)
      ProcedureReturn "y"
    Case 1709847  ;RGB(23,23,26)
      ProcedureReturn "z"
    Case 1775383  ;RGB(23,23,27)
      ProcedureReturn " "
    Case 1840919;RGB(23,23,28) / end of string
      ProcedureReturn Chr(4)  
  EndSelect
EndProcedure


Procedure CreateEmptyDataImage(filename.s)
  If CreateImage(1,1025,1,32)
    SaveImage(1,filename,#PB_ImagePlugin_PNG,10)
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure


Procedure InjectStringToImage(filename.s, StringToInject.s)
  ;all strings will automatic terminated with chr(4)
  result = LoadImage(1,filename,0)
  hdc = StartDrawing(ImageOutput(1))
  If ImageHeight(1) Not 1 And ImageWidth(1) Not 1025
    ProcedureReturn #False
  EndIf
  ;Debug hdc
  If result
    If Len(StringToInject) > 1024
       Debug "String is To long"
       ProcedureReturn #False
    Else
    ;success
    ;lets rock
      For a = 1 To Len(StringToInject)
        currentchar$ = Mid(StringToInject,a,1)
        currentrgbvalue = ConvertCharToRGB(currentchar$)
        ;Debug "currentchar :" + currentchar$
        ;Debug "currentrgbvalue :" + Str(currentrgbvalue)
        ;SetPixel_(hdc,a,0,Val(Str(currentrgbvalue)))
        SetPixel_(hdc,a,0,currentrgbvalue)
      Next a
      SetPixel_(hdc,a+1,0,ConvertCharToRGB(Chr(4)))
      If SaveImage(1,filename,#PB_ImagePlugin_PNG,10)
      Else
        Debug "InjectStringToImage - Error saving"
      EndIf
      StopDrawing()
      ProcedureReturn #True
    EndIf      
  EndIf   
EndProcedure

Procedure.s ExtractStringFromImage(filename.s)
  result = LoadImage(1,filename,0)
  If ImageHeight(1) Not 1 And ImageWidth(1) Not 1025
    ProcedureReturn Str(#False)
  EndIf
  hdc = StartDrawing(ImageOutput(1))
  If result
    ;success
    For a = 1 To 1024
      currentrgbvalue = GetPixel_(hdc,a,0)
      ;Debug currentrgbvalue
      currentchar$ = ConvertRGBToChar(currentrgbvalue)
      ;Debug currentchar$
      If currentchar$ = Chr(4)
        Break
      EndIf
      string$ = string$ + currentchar$ 
    Next a
    ProcedureReturn string$
  Else
    ;error
    ProcedureReturn Str(#False)
  EndIf
  StopDrawing()
EndProcedure


Benutzeravatar
winduff
Beiträge: 879
Registriert: 10.02.2006 21:05
Wohnort: Gießen
Kontaktdaten:

Beitrag von winduff »

Die Idee ist altbekannt, finds aber toll dass das mal jmd. umgesetzt hat.

Nicht probiert, aber wenns geht: Tolle Sache :allright:
Bild
AND51 hat geschrieben:...und ich würde dein Programm aus Wut zwei mal installieren, um eines genüsslicher löschen zu können, als das andere...
myself
Beiträge: 67
Registriert: 18.03.2006 12:48

Beitrag von myself »

ähm kann man nicht jede art von daten ans ende eines bildes schreiben und es ist dann immer noch anzeigbar? Dann versteh ich aber nicht wieso dein code so groß ist, um einen Farbwert ins bild zu schreiben müsstest du nur 4 byte anhängen, um ihn dann auszulesen setzt du den filepointer auf Filesize-4 und liest einen long ein - fertig.
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Beitrag von DarkSoul »

damit kann man daten auf papier speichern :wink:

speichern:
text->bild - build in farbe drucken

lesen:
einscannen und bild zurückkonvertieren.

muss man noch ein paar leitlinien rumzeichnen, falls das bild schief aufm scanner lag usw.
Bild
Marvin
Beiträge: 497
Registriert: 17.07.2005 14:42
Wohnort: Krikkit

Beitrag von Marvin »

Bei PNG müsste man das ganze doch auch über benutzerdefinierte Blöcke im Bild speichern können, oder? :?
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Ich würde die beiden Käse Proceduren noch etwas kürzen :mrgreen:
Beispiel, ungetested:

Code: Alles auswählen

Procedure ConvertCharToRGB(char.s)
  Protected Wert.l = Asc(char) - 96
  If Wert = 4
    ProcedureReturn RGB(23, 23, 28)
  Else
    ProcedureReturn RGB(23, 23, Wert)
  EndIf
EndProcedure
Die andere überlaß ich Dir

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

yo genau...
so schlangen von ifs für eigentlich aufeinanderfolgende werte sind redundant.
selbst wenn die werte völlig unterschiedlich wären,
würde ich das mit einem zuordnungs-array lösen,
dann ggf. mit einer schleife.

noch ein grundsätzlicher Tip:
wenn du $111717 schreibst statt 1120023 kann man das sogar lesen,
welcher kanal welchen wert hat.
die benutzung von RGB() ist also auch redundant,
weil man hex-werte für farben genausogut lesen kann.
für die umsetzung von ts' vorschlag würde das dann etwas komplexer:

Code: Alles auswählen

ProcedureReturn $1717 + $010000 * Wert
da könnte man durchaus RGB() verwenden,
man könnte sich aber auch die multiplikation sparen,
wenn man die information nicht im Blau-Kanal,
sondern im Rot-Kanal (dem niederwertigen) versteckt.

außerdem sollte man ungewünschte ASCII-Werte aussortieren.
man kann ja hier sonderzeichen und sonstwelchen schlumpf mitübergeben,
das wird nicht berücksichtigt, die Proc würde dann schlicht "0" als farbwert zurückgeben.


aber ich finde, man sollte das ganze komplett anders gestalten.

so wie es jetzt konzipiert ist, würden einem ja komische farbverfälschungs-pixel auffallen.
eine bessere möglichkeit wäre z.b. feste positionen für den code zu wählen,
und das nachbar-pixel als referenzwert heranzuziehen.

...werde beizeiten mal was zurechtdaddeln, jetzt gibts ersma futter...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
PureBasic4.0
Beiträge: 785
Registriert: 29.10.2006 17:26
Wohnort: 127.0.0.1

Beitrag von PureBasic4.0 »

text->bild - build in farbe drucken

lesen:
einscannen und bild zurückkonvertieren.
Das wieder einscannen wird unlogisch, jedem normalen Scanner ist es egal, ob da jetzt RGB(0,0,0) oder RGB(0,0,1) ist. Der macht immer schwarz draus, weil man bestimmt keine 1 Pixel große Reihe an schwarzen Pixeln so ausdrucken kann, dass das der Scanner erkennt.[/quote]
PB 4.50 RC1 + Ubuntu 10.04 LTS + Windows 7 x64
Benutzeravatar
Quaxi
Beiträge: 66
Registriert: 11.09.2004 12:42

Beitrag von Quaxi »

Abgesehen davon müssten die daten in CMYK umgerechnet werden nicht in RGB wenn sie ausgedruckt werden sollen.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

von ausdrucken hat ja auch niemand groß geredet, das war nur ein unqualifizierter einwurf von der seitenlinie....

also, um ausdrucken gehts hier garnicht.

holt doch bitte nicht einen zwei monate alten thread wieder hoch,
nur um euch auf das einzige posting zu stürzen, das beim ersten mal erfolgreich ignoriert wurde.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten