Bilderraten

  • C#

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Bilderraten

    Hey Leute,

    Ich habe ein kleines Problem und zwar soll ich in der Schule ein Bilderratespiel in C# machen, bei dem ich die Bilder, die sich in einem Ordner befinden, in ein Array speichern sol. Dann soll random eines der Bilder in eine PictureBox geladen werden und in 4, sich darunter befindende Buttons, sollen 3 Randomnamen und ein mal der richtige Name stehen. ( Bei den Bildern handelt es sich um Tiere und sind als .jpeg gespeichert, mit dem jeweiligen Tiernamen als Dateiname)

    Mein Problem:

    Wie kriege ich die Bilder aus dem Ordner in das Array gespeichert?
    Ich habe zwar schon recht oft mit Arrays gearbeitet, allerdings nicht in Verbindung mit Bildern, geschweige denn mit Dateien, die ich aus externen Ordnern lesen soll...

    Hoffe auf schnelle Hilfe.

    Gruß,
    Leon
    Google mal nach folgendem:
    ​.net msdn list<>
    .net msdn bitmap constructors
    .net msdn io.directoryinfo.getfiles
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

    ThePlexian schrieb:

    Google mal nach folgendem:
    ​.net msdn list<>
    .net msdn bitmap constructors
    .net msdn io.directoryinfo.getfiles


    Und das soll mir in wiefern helfen, die Bilder aus dem Ordner zu lesen? Ich verstehe, dass eine ArrayList wohl schlauer wäre, jedoch besteht mein Problem ja vor allem darin, auf die Dateien im Ordner zuzugreifen, nicht im Speichertyp.
    Hättest du nachdem gegoogelt was dir @ThePlexian vorgeschlagen hat wärst du wahrscheinlich darauf gekommen.

    Guck dir an was für Konstruktoren die Bitmap-Klasse hat und schau was DirectoryInfo.GetFiles macht.
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Hab ich getan, komme aber irgendwie trotzdem nicht drauf...

    Kann mir jemand vielleicht ein konkretes Beispiel geben, wie ich das machen kann?
    Ich suche konkret nach den Bildern in einem bestimmten Verzeichnis, das sich nicht ändert.

    C-Quellcode

    1. string path = "C:/Dokumente und Einstellungen/pc1/Desktop/Leon/Schule/Projekte/Bilderratespiel_Neu/Bilderratespiel_Neu/Tierbilder";
    2. List<Image> pictures = new List<Image>();
    3. private void Ratespiel_Load(object sender, EventArgs e)
    4. {
    5. DirectoryInfo di = new DirectoryInfo(path);
    6. foreach (var file in di.GetFiles(".jpeg"))
    7. {
    8. richtextBox1.Text += "\n" + fi.Name;
    9. }
    10. }


    Habe ich etwas nicht verstanden, oder warum liefert die for-Schleife nichts zurück?

    L30N schrieb:

    di.GetFiles(".jpeg")

    versuchs mal mit di.GetFiles("*.jpeg")

    Warum der Stern?
    Du sagst in diesem GetFiles, dass es dir alle Dateien ausgeben soll, die exakt wie dieser String aussehen. Hätte also eine Datei nur .jpeg als Namen gehabt hättest du sie gefunden.
    Der Stern bedeutet so viel wie alles (eine Wildcard). Da du aber nur Dateien mit .jpeg am Ende haben willst, hängst du das hinten an.
    du findest also alles, das mit .jpeg aufhört. Wenn du eines Tages dich mit Regex beschäftigen musst, wird dir der Stern wieder begegnen ;)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „EaranMaleasi“ ()

    EaranMaleasi schrieb:

    Wenn du eines Tages dich mit Regex beschäftigen musst, wird dir der Stern wieder begegnen

    Nicht nur bei Regex. Normaler Windows-Explorer reicht komplett. Selbst dieser unterstützt den "*". Ebenso google,...


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

    EaranMaleasi schrieb:


    versuchs mal mit di.GetFiles("*.jpeg")


    So, hab es jetzt genau so gemacht, allerdings liefert mir die Schleife noch immer nichts zurück..
    Auch, wenn ich di.GetFiles("*") benutze, sodass er ja eigentlich alle Dateien zurück gibt, passiert nichts.

    Und selbst wenn, hätte ich ja noch das Problem, dass das doch keine Bilddateien sind, sondern bloß Informationen darüber, oder nicht?
    Wenn ich also versuchen würde mit pictures.Add(files); das "Bild" in die Liste einzusetzen, bekäme ich bloß eine Fehlermeldung.
    Ich bin wohl einfach zu blöd dafür xD


    Mein Versuch:

    C#-Quellcode

    1. int zuWaehlendesBild;
    2. string path = "C:/Dokumente und Einstellungen/pc1/Desktop/Leon/Schule/Projekte/Bilderratespiel_Neu/Bilderratespiel_Neu/Tierbilder";
    3. List<Image> pictures = new List<Image>();
    4. Random zufallszahl = new Random();
    5. private void Ratespiel_Load(object sender, EventArgs e)
    6. {
    7. DirectoryInfo di = new DirectoryInfo(path);
    8. foreach (var file in di.GetFiles("*.jpeg"))
    9. {
    10. richTextBox1.Text += file.Name;
    11. }
    12. zuWaehlendesBild = zufallszahl.Next(0, pictures.Count);
    13. PBox_Bild.Image = pictures[zuWaehlendesBild];
    14. }

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „L30N“ ()

    L30N schrieb:

    allerdings liefert mir die Schleife noch immer nichts zurück.
    Teste dies (anderer Pfad, andere Extension):
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Drawing;
    4. using System.IO;
    5. using System.Windows.Forms;
    6. namespace WindowsFormsApplication1
    7. {
    8. public partial class Form1 : Form
    9. {
    10. int zuWaehlendesBild;
    11. string path = @"C:/Temp";
    12. List<Image> pictures = new List<Image>();
    13. Random zufallszahl = new Random();
    14. public Form1()
    15. {
    16. InitializeComponent();
    17. }
    18. private void Form1_Load(object sender, EventArgs e)
    19. {
    20. DirectoryInfo di = new DirectoryInfo(path);
    21. foreach (var file in di.GetFiles("*.png"))
    22. {
    23. richTextBox1.Text += file.Name;
    24. pictures.Add(new Bitmap(file.FullName));
    25. }
    26. }
    27. private void button1_Click(object sender, EventArgs e)
    28. {
    29. zuWaehlendesBild = zufallszahl.Next(0, pictures.Count);
    30. PBox_Bild.Image = pictures[zuWaehlendesBild];
    31. }
    32. }
    33. }
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hab jetzt rausgefunden, woran es lag, dass nichts zurückgegeben wurde.
    Ich habe den selben Code, den ich in 'Ratespiel_Load(...)' hatte, jetzt mal in eine Timerfunktion geschrieben, der startet, wenn die Form lädt, (bisher) die Namen in die Textbox schreibt und wieder stoppt. Was soweit auch gut funktioniert.

    Nur, wie bekomme ich aus dem Typ System.IO.DirectoryInfo, jetzt das eigentliche Bild?
    Bisher habe ich ja nur den Namen.

    An dieser Stelle aber schon mal ein großes 'Dankeschön' an alle hier :)

    L30N schrieb:

    Nur, wie bekomme ich aus dem Typ System.IO.DirectoryInfo, jetzt das eigentliche Bild?
    Bisher habe ich ja nur den Namen.
    Sieh Dir mal meinen Post über Deinem an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke sehr, @RodFromGermany.
    Wenn ich di.GetFiles("*.jpg") benutze, klappt es bisher super.
    Ebenso mit pictures.Add(new Bitmap(file.FullName));.

    Aber wieso? Macht er dann aus dem Pfad eine Bitmap-datei, oder wie soll ich das verstehen?

    L30N schrieb:

    Macht er dann aus dem Pfad eine Bitmap-datei
    Keine Bitmap-Datei, sondern eine Bitmap-Instanz.
    Diese Bitmap-Klasse hat nix mit Dateien der Endung BMP zu tun.
    BMP-Dateien kannst Du genau so in eine Bitmap-Instanz laden:

    VB.NET-Quellcode

    1. Dim myImage = New Bitmap("c:\Temp\Test.bmp")

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ahh okay, danke :D

    Naja das Programm hätte ich dann soweit fast fertig nur eine Sache weiß ich nicht, wie ich die verbessern könnte.
    Und zwar habe ich zwei Listen, ein mal für die Namen und ein mal für die Bilder.
    In 4 buttons, lade ich 3 random namen aus der Liste und in einen (welcher, wird mit einer randomzahl bestimmt) den korrekten Namen für das Bild in der PictureBox.

    Kann ich irgendwie machen, dass bei der Bestimmung der Namen für die anderen 3 Buttons, nie ein Name zwei mal vorkommt?
    ZB dass nich in zwei Buttons, 'Pfau' drin steht, oder so und ebenso, dass nie der richtige Name, in einem der drei 'falschen' Buttons, steht?

    Bisher sieht die Auswahl der Namen und des Bildes, so aus:

    C#-Quellcode

    1. private int CreateRandomNumber()
    2. {
    3. int waehleBild = zufallszahl.Next(0, pictures.Count);
    4. return waehleBild;
    5. }
    6. private void ChooseImageAndNames()
    7. {
    8. zahl = CreateRandomNumber();
    9. PBox_Bild.Image = pictures[zahl];
    10. int rightButton = zufallszahl.Next(1, 5);
    11. switch (rightButton)
    12. {
    13. case 1:
    14. Btn_Auswahl_1.Text = namen[zahl];
    15. Btn_Auswahl_2.Text = namen[CreateRandomNumber()];
    16. Btn_Auswahl_3.Text = namen[CreateRandomNumber()];
    17. Btn_Auswahl_4.Text = namen[CreateRandomNumber()];
    18. break;
    19. case 2:
    20. Btn_Auswahl_1.Text = namen[CreateRandomNumber()];
    21. Btn_Auswahl_2.Text = namen[zahl];
    22. Btn_Auswahl_3.Text = namen[CreateRandomNumber()];
    23. Btn_Auswahl_4.Text = namen[CreateRandomNumber()];
    24. break;
    25. case 3:
    26. Btn_Auswahl_1.Text = namen[CreateRandomNumber()];
    27. Btn_Auswahl_2.Text = namen[CreateRandomNumber()];
    28. Btn_Auswahl_3.Text = namen[zahl];
    29. Btn_Auswahl_4.Text = namen[CreateRandomNumber()];
    30. break;
    31. case 4:
    32. Btn_Auswahl_1.Text = namen[CreateRandomNumber()];
    33. Btn_Auswahl_2.Text = namen[CreateRandomNumber()];
    34. Btn_Auswahl_3.Text = namen[CreateRandomNumber()];
    35. Btn_Auswahl_4.Text = namen[zahl];
    36. break;
    37. }
    38. }

    L30N schrieb:

    nie ein Name zwei mal vorkommt?
    Mach eine Schleife, die Du erst nach Ziehen einer neuen Zahl verlässt
    oder
    mach Dir ein List<int> mit den erlaubten Indizes, wo Du das gezogene Element entfernst
    oder
    mach Dir eine Prozedur, die gleich 3 erlaubte Indizes zurückgibt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Mach eine Schleife, die Du erst nach Ziehen einer neuen Zahl verlässt
    oder
    mach Dir ein List<int> mit den erlaubten Indizes, wo Du das gezogene Element entfernst
    oder
    mach Dir eine Prozedur, die gleich 3 erlaubte Indizes zurückgibt.

    Ich nehme an, dass die Variante mit der Schleife, die langsamste, dafür aber auch die einfachste Methode dafür wäre. Werde ich auf jeden Fall versuchen, danke :)
    Was genau meinst du mit 'Indizes'?

    L30N schrieb:

    Was genau meinst du mit 'Indizes'?

    L30N schrieb:

    C#-Quellcode

    1. namen[CreateRandomNumber()]
    wäre namen[index].
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    L30N schrieb:

    Ich nehme an, dass die Variante mit der Schleife, die langsamste, dafür aber auch die einfachste Methode dafür wäre
    Willst du dein Programm auf nem TI-Taschenrechner laufen lassen?
    Wir reden hier von einigen hundert Ticks dauer. Wie lange ein Tick ist? Bei meinem i5-3350P sinds i-was über 3 Millionen pro Sekunde ;)
    Danke :)

    RodFromGermany schrieb:

    wäre namen[index].

    Danke :)


    Naja ist bloß für die Schule gedacht, sprich auf den Schul-PCs.
    Muss man sich natürlich um die Schnelligkeit einer Schleife nicht großartig Gedanken machen.
    (Auch, wenn die PCs bei mir in der Schule bloß einen Intel Pentium haben, vielleicht auch einen älteren i3, bin ich mir nicht völlig sicher.)

    L30N schrieb:

    Ebenso mit pictures.Add(new Bitmap(file.FullName));.

    Aber wieso? Macht er dann aus dem Pfad eine Bitmap-datei, oder wie soll ich das verstehen?


    Aus dem Pfad wird nichts gemacht, der Pfad steht in seiner Variablen und die wird auch nicht geändert.
    Deine generische Liste hat die Methode Add und die erwartet als Parameter ein Objekt der Klasse Bitmap.
    Mit new instanzierst du ein neues Objekt, Bitmap ist dabei die Klasse, von der du eine Objektinstanz haben willst. Die Klasse Bitmap deshalb, weil sie dafür gedacht ist, Grafiken zu laden und darzustellen. Du nimmst aber nicht den Standardkonstruktor, sondern den Konstruktor, der einen String annimmt, nämlich den Pfad zur Datei, die geladen werden soll. Das ist auch der Grund, weshalb dir empfohlen wurde, nach bitmap constructors zu googeln, wobei du die Lösung ja abgelehnt hast.

    Die Zeile macht also nichts aus deinem Pfad und erstellt keine Bitmap-Datei, sondern sie erstellt eine Bitmap-Instanz, welche deiner Liste hinzugefügt wird.
    Objektorientierung, solltest du mal nachschlagen, falls du mit C# programmieren und es verstehen willst :thumbsup: