Entwickler-Ecke
Windows API - User-Bild anzeigen?
Insignificant - Mo 03.04.06 17:53
Titel: User-Bild anzeigen?
Hallo....ich versuche verzweifelt das User-Bild von dem Windows-Account richtig anzeigen zu lassen, was mir jedoch leider nicht gelingt.
Delphi-Quelltext
1: 2:
| Image1.Picture.Bitmap.LoadFromFile'C:\Dokumente und Einstellungen' + '\All Users\Anwendungsdaten\Microsoft\User Account Pictures\' + GetUser + '.bmp'); } |
Aus irgendeinem Grund werden die Bilder vom User anstatt in den originalfarben, anders dargestellt. (Siehe Anhang) hat jemand eine Idee?
PS.: Wenn komischerweise die original bilder (nicht die User bilder) verwendet, funktioniert es einwandfrei!
nullplan001 - Mo 03.04.06 18:17
Hi all,
spontan fällt mir dazu jetzt nur ein, dass Delphi möglicherweise über eine falsche Palette verfügt. Hat den Nachteil: Wie korrigiere ich das jetzt? Die Standard-Tabelle kann ich dir ohne weiteres geben. Zumindest für 256-Farben-Bitmaps. Weiter geht mein Programm nicht. (Bei dir sind es wahrscheinlich 24-Bit-Bitmaps. Das könnte ein wenig in den Webspace gehen, wenn ich so was posten würde. Sind immerhin 2^24 Farben.)
Cya,
nullplan
Insignificant - Do 06.04.06 13:09
Hmmm....bist du sicher das es daran liegt? Weil komischerweise wird das original Bild davon ja auch in den richtigen Farben dargestellt. Das ist ja das *verwunderliche* an der Sache.
Lossy eX - Do 06.04.06 13:52
Nullplan. Du willst nicht allen erstes für RGB eine Farbtabelle anlegen, oder? Und wenn ja nach welchen Kriterien willst du da gehen? Willst du dir jede Farbe schnappen und dir dazu das passende Gegenstück raus suchen?
Also wenn ich das auf den kleinen Bildern richtig sehen kann, dann würde ich spontan behaupten, dass Blau zu Grün geworden ist. Grün zu Rot. Und Rot müsste dann eigentlich Blau sein. Ich würde einfach mal das Bild nach dem Laden Pixel für Pixel durchgehen (mittels Scanlines) und dann die Kanäle tauschen.
PS: Zeigt denn ein Windowsbetrachter die Bilder richtig an. Also so etwas wie IrfanView?
F34r0fTh3D4rk - Do 06.04.06 15:15
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TForm1.Button1Click(Sender: TObject); var x, y: integer; myrgb, r, g, b: integer; begin image1.Picture.LoadFromFile('C:\Dokumente und Einstellungen\All Users\Anwendungsdaten\Microsoft\User Account Pictures\' + getuser + '.bmp'); for x := 0 to image1.Width do for y := 0 to image1.Height do begin myrgb := colortorgb(image1.canvas.pixels[x, y]); r := GetBValue(myrgb); g := GetRValue(myrgb); b := GetGValue(myrgb); image1.canvas.pixels[x, y] := rgb(r, g, b); end; end; |
mit scanlines gehts natürlich schneller ;)
falls du das für jeden user machen willst, solltest du den pfad dynamisch laden, kann ja sein, dass jemand kein deutsches win hat, bzw windows auf I:\ so wie ich ;)
Insignificant - Do 06.04.06 15:40
Ja, mein Bildbetrachter zeigt die Bilder richtig an.
Ich habs nun nach deinem Beispiel gemacht F34r0fTh3D4rk und ich muss sagen es sieht schon wesentlich besser aus.
Aber naja *perfekt* isses noch immer nicht...
PS.: In meiner Anwendung ist der Pfad schon dynamisch, ich dachte mir aber es sei sinnvoller fürs Forum den pfad so auszulesen damit auch jeder weiss wo was ist und so ^^
nullplan001 - Do 06.04.06 17:03
Hmmm... sieht so aus, als würde er die Farben zu grell kriegen. Lade mal die Grafiken in Paint und vergrößere beide sehr stark. Delphi macht den Stängel rosa und blau, anstatt grau und weiß. Falsche Sättigung und Helligkeit? Och nö... Wie du das verbessern kannst, weis ich leider nicht (siehe Rand: Ich hab kein Delphi, daraus folgt: keine Delphi-Hilfe, keine Beschreibung von TImage1). Aber könnte sein, oder?
Tschö,
nullplan
Lossy eX - Fr 07.04.06 09:40
Zu Not poste mal das BMP was du versucht darzustellen. Dann können wir uns das mal anschauen. Das dürfte wohl mehr bringen als hier jetzt so rumzuraten.
Lossy eX - Mo 10.04.06 09:25
Sorry, dass es ein bisschen länger gedauert hat.
Okay. Ich habe eine Gute und eine schlechte Nachricht. Die Gute. Das Bitmap scheint augenscheinlich in Ordnung zu sein und ich weiß warum es Delphi da aushebt. Die Schlechte ist allerdings die, dass ich nicht genau weiß wie man es umgehen soll. ;-)
Also einmal mit IrfanView abgeseichert und dann mit einem Hexeditor die beiden Dateien vergleichen lassen. Und siehe da. Anscheinend ist in den Originalbildern ein Flag anders gesetzt. Dieses ist eine Größenangabe für den Bitmapheader und das ist anders als es eigentlich üblich wäre. So wie es scheint interpretiert Delphi diese Infos nicht so ganz richtig. Er beginnt nämlich 10 Bytes früher mit dem Lesen als die Daten beginnen.
Das TBitmap ist aber leider nicht so berauschend was das einlesen der Bilder angeht. Der kommt unter anderem auch nicht mit größeren Größenangaben klar, falls diese angeben, dass am Ende der Datei zwei nullzeichen vorhanden sind. Hatte ich auch schon. Leider gibt es nicht wirklich viele Alternative.
Wie auch immer. Denke mal zu Darstellen dieser Bilder musst du die Dateien per Hand laden. Du kannst die Daten ja auch in einem TBitmap ablegen. Darfst sie aber nicht damit laden. Musste mal im Forum schauen. Da gibt es schon den ein oder anderen Code dazu.
F34r0fTh3D4rk - Mo 10.04.06 10:08
liegt der flag immer beim gleichen offset ?
wenn die position statisch ist, kann man da programmintern vielleicht ein wenig was drehen
Lossy eX - Mo 10.04.06 10:37
Eigentlich schon. Aber daraus resultierend musst du die Größe auch entsprechend ändern und die kompletten Daten verschieben. Ich denke mal es wäre wesentlich einfacher, wenn man den Header einliest und dann entsprechend auf das Offset reagiert und es überspringt. Und dann die Daten ganz normal in Scanlines einliest.
Insignificant - Mo 10.04.06 12:55
Und wie genau macht man sowas? Verstanden so in etwa was Sache ist und wie man das dann evt. umgehen kann habe ich schon. Nur keine Ahnung wie man sowas in irgendeiner Art und Weise in die Praxis umsetzt.
Darth Sitthiander - Sa 15.04.06 13:39
Ich glaube man muss nur den pfad direkt eingeben, dann gehts bei mir. Jetzt hab ich da ein problem. Wie kann ich herausfinden wo der user diese bilder gespeichert hat? Muss ich das per registry machen oder gibt es da eine function für? Danke im Vorraus.
nullplan001 - So 16.04.06 10:38
Hi all,
hab ich dich richtig verstanden, die Bilder liegen in %systemdrive%\Dokumente und Einstellungen\%username%\Anwendungsdaten\blabla ? Das kann man rauskriegen. Kurz geschrieben heist der Pfad nämlich eingentlich %userprofile%\Anwendungsdaten\blabla. %userprofile% kriegst du mit getenv raus (Wer die Variable verändert, ist selbst schuld, Windows stützt sich nämlich beim Laden des Profils auf diese Variable -> Veränderung = Tod von Windows.) Wenn du bei getenv nur einen leeren String rauskriegst, ist die Variable nicht gesetzt, oder enthält einen leeren String. In dem Fall ist Windows ziemlich schlecht dran. Aber hier die Funktion:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| function getPictureDir:string; var isNT : boolean; tmp : string; begin isNT := (getenv('OS') <> ''); if isNT then begin tmp := getenv('userprofile'); if tmp = '' then tmp := 'C:\Dokumente und Einstellungen\All Users\Anwendungsdaten\blabla' else tmp := tmp + '\Anwendungsdaten\blabla'; end else Result := tmp; end; |
HTH und tschö,
nullplan
Darth Sitthiander - Mo 17.04.06 01:33
Das erscheint mir schon logisch, aber ich hätte es gern 100%tig richtig. Bei mir heisst der ordner nämlich seit derwindowsinstallation all users.windows. Hoffentlich gibt es da eine lösung. Danke.
nullplan001 - Mo 17.04.06 17:42
Naja, das ist ja auch nur eine Notlösung. Hmm... für All Users heist die Umgebungsvariable %alluserprofile%. Aber auch die kann ungesetzt oder undefiniert sein. Kannst ja noch etwas in der Richtung einbauen. Sieht dann so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| function getPictureDir:string; var isNT : boolean; tmp : string;
begin isNT := (getenv('OS') <> ''); if isNT then begin tmp := getenv('userprofile'); if tmp = '' then if getenv('alluserprofile') = '' then tmp := 'C:\Dokumente und Einstellungen\All Users\Anwendungsdaten\blabla' else tmp := getenv('alluserprofile') + '\Anwendungsdaten\blabla' else tmp := tmp + '\Anwendungsdaten\blabla'; end else Result := tmp; end; |
Oh, verschachtelte if's. Kann sein, dass da eine LostSemicolonException auftritt. Ach, war ja jetzt gar nicht Java ;) :lol: Naja, ich denke, dass das deine bedenken beheben sollte: Wenn es keine %userprofile% gibt, nimm %alluserprofile%, wenns das nicht gibt, nimm Standardpfad. Should be it.
HTH und Tschö,
nullplan
Darth Sitthiander - Di 18.04.06 00:41
Ich hanbs jetzt mal mit nem label getestet, und bei mir steht der nach knopfdruck leer. code und so hab ich drin^^. Stimmt diese Funktion?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| function GetEnv(Variable:string):string; var buffer:array[1..1024] of char; begin if GetEnvironmentVariable( pChar(variable) , @Buffer, Sizeof(buffer) )=0 then result:='' else result:=buffer; end; |
nullplan001 - Di 18.04.06 17:08
Hi all,
Delphi kennt kein getenv()? Schwach, wie ich finde, aber ... solange sich dein Code kompilieren lässt, und du ihn an prominenten Beispielen wie PATH getestet hast, sollte nichts schief gehen (Unter TP und FP gibt es eine Funktion namens getenv, die einem alle Arbeit in die Richtung abnimmt: Wenns sie nicht gibt, gibts nen leeren String, sonst den Inhalt der Variablen)
Tschö,
nullplan
P.S.: solltest du je für ein UNIX-basiertes Betriebssystem schreiben: Dort sind die Umgebungsvariablen Case-Sensitiv. Aber Windows ist da zum Glück nicht so.
Darth Sitthiander - Di 18.04.06 17:23
:lol: :lol: :lol: :lol:
Also ich würde gerne für Windows und mit Delphi schreiben. Aber gibt es denn da gar keine Lösung? Weisst du wo alle Umgebungsvariablen sind? Also jeder Pfad, der bei der windowsinstallation dabei ist? Danke schonmal.
nullplan001 - Mi 19.04.06 14:10
Hi all,
also, ich rate dringend davon ab, die Umgebungsvariablen aus der Registry zu zaubern, weil die
- von Version zu Version woanders sein können
- GetEnv (oder wie das halt gerade heist) die Umgebungsvariablen immer rauskriegt
- nicht alle Umgebungsvariablen in HKLM\Environment oder HKCU\Environment zu finden sind (z.B. %cd%, die den aktuellen Pfad rausfindet (braucht man nur in Batches))
Aber wenn du nur die statischen Variablen haben willst: Öffne eine CMD und tippe ein: cmd /?. Der darauffolgende Hilfetext sollte irgendwo den Speicherort der Variablen anzeigen. Unter Win2k eben HKCU\Environment für die Benutzervariablen und die Systemvariablen in HKLM\Environment.
Und was GetEnv angeht: nimm mal DOS in die USES-Klausel auf. Das sollte dein problem beheben. Wenn er das nicht hat, nimm deinen Code.
Tschö,
nullplan
Darth Sitthiander - Do 20.04.06 13:25
ES gibt dort aber kein Dos.dcu. Kannst du mir ein Projekt machen mit dem man einen button hat und dann direkt wenn man darauf klickt das userbild in ein image geladen wird? Danke, das würde alles für mich leichter machen zu verstehen.
nullplan001 - Do 20.04.06 18:03
@Dath Sittiander:Würde ich gerne, wenn ich Delphi hätte. Statt dessen schreibe ich dir ein Konsolen-Programm, was den Pfad der Bilder zurückliefert und hänge es samt Quelltext an. Bitte warten... So fertig. Weil du's bist, pack ich noch eine DLL oben drauf, die die Funktion getenv enthält. Bitte sehr.
Tschö,
nullplan
Darth Sitthiander - Fr 21.04.06 10:41
Danke für die Beiden Tipps. Habs jetzt irgendwie kombinieren können^^ Und bei meinem Bruder funktioniert es jetzt. Danke vielmals!
nullplan001 - Fr 21.04.06 18:38
Man hilft doch gern :D
Tschö,
nullplan
turboPASCAL - Do 24.08.06 21:38
Hi,
der Thread ist zwar schon alt, da ich das selbige Problemchen mit den Bitmaps hatte
will ich mal hier noch eine Lösung vorschlagen.
Delphi kommt mit den von Windows angelegten Bitmaps nicht zu recht, alsoeinfach die Bitmaps von Win. laden lassen und gut ist's. ;)
Delphi-Quelltext
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:
| implementation
{$R *.dfm}
uses ShlObj;
function TForm1.CommonDataPath: string; const CSIDL_COMMON_APPDATA = $0023; var Path: array [0..1024] of char; begin if SHGetSpecialFolderPath(Handle, Path, CSIDL_COMMON_APPDATA, TRUE) then Result := String(path) else Result := ''; end;
function TForm1.GetCurrentUserName: String; var pcUserName : pChar; dwMaxChars : dWord; const MAXCHARS = 255; begin dwMaxChars := MAXCHARS; GetMem(pcUserName, MAXCHARS + 1); if GetUserName(pcUserName, dwMaxChars) then Result := String(pcUserName) else Result := ''; FreeMem(pcUserName); end;
procedure TForm1.FormCreate(Sender: TObject); var LgPath: String; begin Label1.Caption := GetCurrentUserName;
LgPath := CommonDataPath + '\Microsoft\User Account Pictures\' + Label1.Caption + '.bmp';
if FileExists(LgPath) then begin Image1.Picture.Bitmap.Handle := LoadImage(0, PChar(LgPath), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); end else ShowMessage(format('%s'#13#10'"%s"', ['Datei nicht gefunden:', LgPath])); end; |
http://www.delphipraxis.net/post599701.html#599701
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!