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.
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
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.
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.