Hallo Formmitglieder und Besucher, ich habe folgendes Problem, bitte fragt nicht, warum ich das brauche. Bin noch am Probieren. Ich habe eine Variable mit Länge 100 uint16_t (Bild) [100] = {....}; In möchte je nach externer Voraussetzung einige "short" (damit meine ich die 2x char, da Variable 16 bit lang ist) weglassen. Der Trick dabei ist, die weg gelassenen Daten sollen über die ganze (100) Länge möglichst gleichmäßig verteilt werden. Beispiel: Möchte ich nur die Hälfte haben, nehme ich jeden 2. uint16_t. Möchte ich 25% haben, nehme ich jeden 4. uint16_t. Was muss ich machen, damit ich beispielsweise 42% bekomme? die ersten 42 uint16 weg zu machen geht nicht. Die müssen gleichmäßig auf die ganze "Datei" verteilt sein. Vielen Dank im Voraus für konstruktive Ideen.
In einem Array ...[100] kann man zwar Werte uninitialisiert lassen, aber nicht auslassen. Irgendetwas steht immer in den Zellen. Ob Dir der jeweilige Wert gefällt ist eine andere Sache. Was für ein Unsinn entsteht, wenn nicht zusammenpassende Teiler vorkommen, kannst Du selber sehr einfach feststellen: Zähle einfach an den Fingern bis 4 und dann nochmal und dann (beim 3. Mal) musst Du Dir wenigstens zwei Finger borgen...
>Irgendetwas steht immer in den Zellen. Ob Dir der jeweilige Wert gefällt >ist eine andere Sache. Ganz klar. Ich möchte ein Bild langsam unsichtbar machen. Das bedeutet die Bilddateien, die zum Display geschickt werden sind zuerst komplett da. Danach möchte ich langsam Schritt für Schritt immer mehr Pixel weglassen. ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ^^ komplettes Bild ++ ++++ ++ +++ ++ +++ + +++++ ++ +++ +++++ + ++++++++ ++++++ +++ ++++ +++++ ^^ Bild mit weniger Pixeln, bzw anders gesagt, die Pixel werden durch weiße Farbe ersetzt. Ich möchte nun ausrechnen, wo die weißen Pixel sein sollen damit die möglichst gleichmäßig im Bild verteilt sind.
Hier nicht angemeldet schrieb: > Was muss ich machen, damit ich beispielsweise 42% bekomme? > die ersten 42 uint16 weg zu machen geht nicht. Die müssen gleichmäßig > auf die ganze "Datei" verteilt sein. Stichwort Bresenham Algorithmus. Wird auch zum Linienzeichnen in beliebigen Winkeln verwendet. fchk
man kann doch unmöglich das komplette Gerät beschreiben. Ich versuche das vereinfacht: Eine Bilddatei (Firmenlogo) liegt im EEPROM und chillt dort, bis ich damit was machen möchte. Die Datei ist paar KB groß. Beim Ausschalten des Gerätes soll das Logo angezeigt werden, in dem die Daten aus der eeprom Adresse für Adresse ausgelesen werden und zum Display geschickt werden. Zuerst erscheint im Display das komplette Bild. Danach sollen immer mehr Pixel durch schwarze Pixel ersetzt werden, bis das Bild verschwunden ist. Das Ganze soll etwa 1,5 sekunden dauert (<- wobei das schon komplett egal ist ist). Der Plan war, das Bild immer wieder zum Display zu schicken, wo immer mehr schwarze Pixeln drin sind. Die Daten werden aus dem eeprom gelesen und gleich zum Display geschickt. Also muss ich bereits beim Auslesen wissen, ob ich den Wert aus der aktuellen eepromadresse durch schwarzen Pixel ersetzen soll. Anderer Ansatz wäre, viele Bilder an PC zu erstellen, wo immer mehr Pixel schwarz sind, aber das ist Platzverschwendung im eeprom. Ich hoffe, es ist nun verständlich, was ich meine.
Hi >Eine Bilddatei (Firmenlogo) liegt im EEPROM und chillt dort, bis ich >damit was machen möchte. >Die Datei ist paar KB groß. An welcher Hilfsschule hast du Programmieren 'gelernt'? So etwas mache ich in Assembler. Außerdem fehelen wichtige Informationen. Z.B. ist das Display lesbar? MfG Spess
Moin, Da wuerd' ich mir eine Pseudonoisefolge generieren und damit dann die zu schwaerzenden Pixel "herausfinden". Dadurch, dass es "Pseudo" Noise ist, kannst du sicherstellen, dass nach X Schritten das gesamte Bild schwarz ist. Gruss WK
spess53 schrieb: > Außerdem fehelen wichtige Informationen. Z.B. ist das Display lesbar? Das Display ist nicht lesbar. Wie das Display genau funktioniert weiß ich gar nicht so richtig. Um das Display kümmert sich ein anderes Team. Wir haben einfach die Schnittstelle abgesprochen. Welche Befehle was mit dem Display machen. Das Display bekommt eine eigene Platine, um die sich eine andere Gruppe der Menschen kümmert. Eigentlich gar nicht nötig, aber es sollten mehrere Teams gebildet werden.
Hier nicht angemeldet schrieb: > Der Plan war, das Bild immer wieder zum Display zu schicken, wo immer > mehr schwarze Pixeln drin sind. Warum so kompliziert? Kann man auf diesem LCD keine einzelnen Pixel setzen? Selbst wenn nur immer einen gewissen Bereich schreiben kann, 8 Pixel zB, wäre es doch viel einfacher immer einen gewissen Bereich zu lesen, ein Pixel zu ändern und dann nur diese 8 wieder zu senden. Welches LCD verwendest du?
Hier nicht angemeldet schrieb: > Um das Display kümmert sich ein anderes Team. > Wir haben einfach die Schnittstelle abgesprochen. Und was läst diese Schnittstelle alles zu? Ja doch hoffentlich nicht nur ein ganzes Bild zu senden.
Flo85 schrieb: > Und was läst diese Schnittstelle alles zu? Ja doch hoffentlich nicht nur > ein ganzes Bild zu senden. Da wir alle Anfänger sind, leider ja. Es gibt ein Befehl für den Text, dann zum Display löschen und halt für die Grafik. Grafik ist einfach als Datenstrom definiert. Das heißt alle Bilddateien von Anfang bis Ende. Die Displayplatine macht den Rest. Welches Display das genau ist, kann ich leider nicht sagen, ist nicht mein Part. Ist das wirklich nicht mit einer "for schleife und zweidimensionalem Array" zu lösen? Das ist nicht der Kern des Projektes, daraus sollte keine Doktorarbeit gemacht werden. Quick and dirty, etwas Spielerei für Auge.
spess53 schrieb: >>Eine Bilddatei (Firmenlogo) liegt im EEPROM und chillt dort, bis ich >>damit was machen möchte. >>Die Datei ist paar KB groß. > > An welcher Hilfsschule hast du Programmieren 'gelernt'? Wie kommst du darauf, dass er es gelernt hat und nicht gerade dabei ist, es zu lernen? > So etwas mache ich in Assembler. Er hat nicht nach einer Sprache gefragt, sondern nach einem Algorithmus. > Außerdem fehelen wichtige Informationen. Z.B. ist das Display lesbar? Hä? Warum sollte die wichtig sein für die Frage, wie man am besten eine einigermaßen gleichmäßige Verteilung der "weggelassenen" Pixel erreicht? Die einzige bisher sinnvolle Antwort: Frank K. schrieb: > Stichwort Bresenham Algorithmus. Wird auch zum Linienzeichnen in > beliebigen Winkeln verwendet. Hier nicht angemeldet schrieb: > Was muss ich machen, damit ich beispielsweise 42% bekomme? Du legst eine Zählvariable an. Dann gehst du durch dein Array Element für Element durch. Für jedes Element addierst du 42 zu der Zählvariable. Danach machst du einen Vergleich: Wenn die Variable kleiner als 100 ist, nimmst du den Pixel und machst weiter. Wenn sie dagegen 100 oder größer ist, ziehst du 100 von ihr ab und läßt den Pixel weg. So gehst du durch dein ganzes Array durch. Am Ende hast du auf diese Weise 42% der Pixel in so regelmäßigen Abständen, wie es geht, weggelassen.
Zufällige Adressen für Display-Punkten generieren und einfach 0 senden für schwarze Farbe.
@ Rolf Danke, du hast das richtig verstanden! Ich werde das morgen genauer lesen und versuchen um zu setzen. Klingt komplett logisch und machbar so.
Das Logo hat N Pixel, nimm eine Primzahl P < N. for ( x = 0, i = 0; i < N, i++ ) { Pixel(x) = SCHWARZ; x = (x + P) % N; }
Upps, um halbwegs C-konform zu bleiben, muss es natürlich heißen: Pixel[x] = SCHWARZ; Ansonsten ist es mehr als Algorithmus-Vorschlag gedacht, weil von so einem Pixel natürlich alle Farbkanäle (oft 3 Byte) auf den SCHWARZ-Wert gesetzt werden müssen...
Jalob schrieb: > Das Logo hat N Pixel, nimm eine Primzahl P < N. > > for ( x = 0, i = 0; i < N, i++ ) > { Pixel[x] = SCHWARZ; > x = (x + P) % N; > } Hallo Jalob, kannst du das für mich bitte erklären? Wo ist in der Gleichung die Menge als Variable, die weg gelassen werden soll? Der TE wollte Beispielsweise 42% weg haben. Nur so, weil ich die Logik verstehen will. Gruß Alex
@ Rolf Magnus Vielen Dank nochmals! Wir haben das so umgesetzt und es hast gleich beim ersten Mal funktioniert.
Hey Alex, ich dachte, das erkennt man "mit bloßem Auge". Also dann: Das Logo hat N Pixel, nimm eine Primzahl P < N und einen Endwert E = N * 0,42. for ( x = 0, i = 0; i < E, i++ ) { Pixel[x] = SCHWARZ; x = (x + P) % N; } Die Primzahlgeschichte sieht nicht aufregend "zufällig" aus, hat aber den Vorteil, dass jedes Mal ein neues Pixel getroffen wird, so dass nach N Schritten wirklich alles weg ist. Und nach N/2 Schritten genau die Hälfte... Mit echten (und auch fast immer bei Pseudo-)Zufallszahlen wird die Trefferrate für nicht schon vorher geschwärzte Pixel mit dem Ablauf immer kleiner. -> Schwer vorhersagbar, wann 42% getroffen wurden. Es gibt aber schöne Ausnahmen: Die Anzahl der Pixel N lässt sich als 2^n (n ist eine positive Ganzzahl) darstellen. Z.B. 256, 512, ... 16384. Ein LFSR mit der Lauflänge L = N - 1 würde auch mit jedem Schritt genau ein Pixel löschen, die optische Wirkung ist von Zufall kaum zu unterscheiden! Klitzekleiner Nachteil: Die NULL ist verboten, Pixel[0] muss also irgendwann "von Hand" gelöscht werden. Ist die Lauflänge L größer, als die Pixelzahl, funktioniert das auch noch recht gut. Allerdings darf man NICHT Löschen, wenn x >= N ist!!! 42% erreichst du ZIEMLICH GENAU, wenn i bis 42% von L zählt. 100% (außer der NULL) sind erreicht, wenn i bis L-1 gezählt hat.
Das was Du brauchst ist hier beschrieben: http://www.swisseduc.ch/informatik/120-lektionen/programmier-projekt-processing/processing/src/reichert/_02_bildbearbeitung/bildbearbeitung.html Den Rest musst Du Dir selbst herleiten.
Die Frage ist, ob geänderte Pixel so bleiben sollen oder nicht. Ob das Bild beim Verschwinden flimmern soll/darf oder nicht. Wenn es nicht flimmern soll, braucht man eine feste Reihenfolge, in der die Pixel auftauchen oder verschwinden sollen. Dafür ist es dabei unwesentlich, ob im Zustand 42 oder anderen die Pixel haargenau optimal verteilt sind, da das Auge sowieso nicht so schnell hinterher kommt. Das erste Pixel wäre zB das in der Mitte. Das zweite das in der Mitte der ersten Hälfte, das dritte in der Mitte der zweiten Hälfte. Im Zustand 2 wäre die Verteilung nicht ausgeglichen, sondern asymmetrisch. Das macht aber nichts, da unmittelbar darauf der ausgeglichene Zustand 3 folgt. Ich habe das mal mit Kreisen gemacht. Eine Tabelle der Pixel angelegt, sortiert nach der Entfernung von einem Mittelpunkt. Dann die Pixel allmählich nach dieser Tabelle gesetzt. Der Effekt war verblüffend. Obwohl das Display ziemlich pixelig war, schien der Kreis ganz kontiuierlich zu wachsen.
Bei Bildern verwendet man für so etwas eher "Dithering": https://de.wikipedia.org/wiki/Dithering_(Bildbearbeitung) Das bei den Displays mit geringer Pixelzahl oder Schwarz-Weiß-Displays, die Graustufen darstellen sollten, recht üblich. Wenn Du in Google "Bild Dithering" eingibst, kannst Du Dir in der Bildersuche die Wirkung anschauen. Ich vermute, dass ein gleichmäßiges Muster keine schöne Wirkung haben wird. Es gibt gut beschriebene Algorithmen dafür: https://de.wikipedia.org/wiki/Floyd-Steinberg-Algorithmus Du könntest Dein Schwarz-Weiß Bild als Graustufenbild betrachten und dann einfach schrittweise die Helligkeit verringern und per Dithering neu zeichnen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.