Zum Inhalt springen

16 höchsten Werte aus einem Array ermitteln


Empfohlene Beiträge

Geschrieben

Hallo,

ich habe folgendes Problem:

In einer Routine verwende ich ein Array aus 27 einzelnen Zahlen.

int[] palcount = new int[27];

Dieses Array wird nun in jedem Index unterschiedlich "gefüllt".

              for (int p = 0; p < cols; p++){

                  if (getCol(p).getBlue() == CPCBlue &&

                      getCol(p).getRed() == CPCRed &&

                      getCol(p).getGreen() == CPCGreen){

                      palcount[p]++;

                      pen = p;

                      break;

                  }

              }
Dieses funktioniert auch wunderbar soweit. Die Frage ist nun: Wie kann ich aus diesem Array ein Zweites Array [16] aufbauen, welches die 16 höchsten Werte aus dem ersten Array enthält? Höchster Wert ist noch unbekannt. Diesen zu ermitteln, habe ich auch noch herausbekommen:
              int highest = 0;

              for (int p = 0; p < 27; p++){

                  if (palcount[p] > highest)

                      highest = palcount[p];

              }

Wäre wirklich super, wenn mir da jemand weiterhelfen könnte.

Geschrieben

*Grumpf*

Gestern war es schon spät.

Problem:

Ich benötige den Index von pencols; in aufsteigender Reihenfolge.

Beispiel:

pencols[1] = 5

pencols[2] = 3

pencols[3] = 8

Ausgabe:

3,1,2

Das Ziel soll es sein, aus einer Farbauswahl von 27 Farben die 16 am häufigsten verwendeten Werte zu finden.

Geschrieben

ok, du willst jetzt also die Indexe der 16 höchsten Werte speichern?


		List<Integer> maxPencols = new ArrayList<Integer>();


		for(int i = 0; i < 16; i++) {

			int indexMax = 0;

			for(int j = 0; j < pencols.length; j++) {

				if(!maxPencols.contains(j) && pencols[j] > pencols[indexMax])

					indexMax = j;

			}

			maxPencols.add(indexMax);

		}

Geschrieben

Danke sehr,habe es dann auch endlich hinbekommen, indem ich 2 Arrays verwende.

Schliesslich muss ja auch die Sortierung von hoch nach niedrig erfolgen.

(sort liefert es ja genau umgekehrt)

Dieses ist das Ergebnis:

Ich kann nun Bilder im JPG, PNG, BMP oder GIF Format auf das Schneider CPC System umwandeln.

Dabei wir das Bild geladen, es wird in 27 feste Farbwerte neu berechnet, und aus diesen 27 Farbwerten werden dann die 16 am häufigsten verwendeten Farben für eine Palette genommen und dann wird das Bild direkt in den CPC-Bildschirmspeicher gepoked:

image_import.gif

Geschrieben

Hier übrigens meine Routine dazu:

   public void convert(boolean detect){

       if (loadImg == null)

           return;

      int width = loadImg.getWidth();

      int height = loadImg.getHeight();

      if (width > 640)

          width = 640;

      if (height > 400)

          height = 400;

      int xstep = 0, ystep = 2;

      if (mode == 1)

          xstep = 2;

      if (mode == 2)

          xstep = 1;

      if (mode == 0)

          xstep = 4;

      palcount = new int[27];

       for (int x = 0; x < width; x+=xstep)

          for (int y = 0; y < height; y+=ystep)

          {

              Color test = new Color(loadImg.getRGB(x, y));

              sourceRed = test.getRed();

              sourceBlue = test.getBlue();

              sourceGreen = test.getGreen();

              int dark = 85;

              int medium = 170;

              if (sourceRed < dark)

                  CPCRed = 0;

              else

              if (sourceRed >= dark && sourceRed <=medium)

                  CPCRed = 0x60;

              else

                  CPCRed = 0xff;

              if (sourceGreen < dark)

                  CPCGreen = 0;

              else

              if (sourceGreen >= dark && sourceGreen <=medium)

                  CPCGreen = 0x60;

              else

                  CPCGreen = 0xff;

              if (sourceBlue < dark)

                  CPCBlue = 0;

              else

              if (sourceBlue >= dark && sourceBlue <=medium)

                  CPCBlue = 0x60;

              else

                  CPCBlue = 0xff;

              int cols = 2;

              if (mode == 1)

                  cols = 4;

              if (mode == 0)

                  cols = 16;

              if (detect)

                  cols=27;

              pen = 0;

              if (detect)

                  pen=27;

              if (detect)

              for (int p = 0; p < cols; p++){

                  if (getCol(p).getBlue() == CPCBlue &&

                      getCol(p).getRed() == CPCRed &&

                      getCol(p).getGreen() == CPCGreen){

                      palcount[p]++;

                      pen = p;

                      break;

                  }

              }else

              for (int p = 0; p < cols; p++){

                  if (CPC.setCol(p).getBlue() == CPCBlue &&

                      CPC.setCol(p).getRed() == CPCRed &&

                      CPC.setCol(p).getGreen() == CPCGreen){

                      palcount[p]++;

                      pen = p;

                      break;

                  }

              }

                  int cpcX = x;

                  int cpcY = y/2;

                  if (mode == 0)

                      cpcX/=4;

                  if (mode == 1)

                      cpcX/=2;

                  if (!detect)

                  CPC.PLOT(cpcX, cpcY, pen, mode);


          }


      if (detect){

      int count = 0;

      int[] check = new int[27];

      outcount = new int[27];

      for (int p = 0; p < 27; p++)

          check[p] = palcount[p];


      java.util.Arrays.sort(check);

      int [] recheck = new int[27];


      for (int p = 0; p < 27; p++)

          recheck[p] = check[26-p];

      check = recheck;

      for (int p = 0; p < 27; p++){

          for (int q = 0; q < 27; q++){

              if (palcount[q] == check[p]){

                  outcount[count] = q;

                  count++;

              }

              if (count==17)

                  break;

          }

      }


      System.out.print("FOR T=0 TO 15:READ A:INK T,A:NEXT:DATA ");

      for (int pf = 0; pf < 16; pf++){

          //*b7d4, b7e5 = CPC 6128

          CPC.POKE(0xb7d4+1+pf, GAInks[outcount[pf]]);

          CPC.POKE(0xb7e5+1+pf, GAInks[outcount[pf]]);

          System.out.print(outcount[pf]);

          if (pf<15)

              System.out.print(",");

      }

      System.out.println();

      }

   }

Das void Convert(...) wird 2x aufgerufen:

- Zuerst wird die beste Palette berechnet

- Wenn dieses erfolgt ist, wird das Bild nochmal neu berechnet und auf die erstellte Palette optimiert.

Geschrieben
Danke sehr,habe es dann auch endlich hinbekommen, indem ich 2 Arrays verwende.

Schliesslich muss ja auch die Sortierung von hoch nach niedrig erfolgen.

(sort liefert es ja genau umgekehrt)

Warum so kompliziert. Du führst sort auf Dein Array aus und lässt Dir via Arraycopy System (Java 2 Platform SE v1.4.2)

die letzten n Farbwerte des Array liefern.

Außerdem heißt, dass was Du da machst "Histogramm" und dafür gibt es auch schon passende Tools von Sun Image Analysis

Damit kannst Du die Bin / Container angeben, das wären bei Dir 27 und die Grenzen, somit errechnet er Dir das direkt passend

Geschrieben

Dabei wir das Bild geladen, es wird in 27 feste Farbwerte neu berechnet, und aus diesen 27 Farbwerten werden dann die 16 am häufigsten verwendeten Farben für eine Palette genommen

Das kommt mir seltsam vor. Warum 27? Warum erst daraus eine 16 Farben-Palette bilden?

Geschrieben
Das kommt mir seltsam vor. Warum 27? Warum erst daraus eine 16 Farben-Palette bilden?

Der CPC hat 27 verschiedene Farben, von denen er maximal 16 gleichzeitig darstellen kann.

Also möchte ich wissen, welche 16 Farben aus den 27 Möglichen die Passendsten sind.

Geschrieben
Der CPC hat 27 verschiedene Farben, von denen er maximal 16 gleichzeitig darstellen kann.

Ahso, die 27 Farben sind also fest.

Soll das ferstige Bild mit oder ohne Dithering farbreduziert werden? Bisher machst Du es ja ohne.

Es gibt diverse Algorithmen, um eine Farbpalette zu bilden. Für diesen Spezialfall mit einet Palette von 16 Farben aus 27 festen Farben, müsste man aber vermutlich bei vielen Verfahren Anpassungen vornehmen.

Geschrieben
Ahso, die 27 Farben sind also fest.

Soll das ferstige Bild mit oder ohne Dithering farbreduziert werden? Bisher machst Du es ja ohne.

Es gibt diverse Algorithmen, um eine Farbpalette zu bilden. Für diesen Spezialfall mit einet Palette von 16 Farben aus 27 festen Farben, müsste man aber vermutlich bei vielen Verfahren Anpassungen vornehmen.

Das "Gesamte" ist leider viel zu komplex, um es zu erklären.

Dazu müsste man sich mit dem gateArray des CPC auskennen, über PEEKS und POKES für den CPC bescheid wissen und noch sehr viel mehr.

Eins aber:

Das, was auf dem Display erscheint, ist kein "Bild", wie man es kennt, also kein Bitmap. Es besteht aus tausenden von Bildschirmpixeln (160x200 um es genau zu nehmen)

Ich muss also sehr mühevoll ein Bild in seine Pixel zerlegen und dann auch noch an die richtigen Adressen POKEn (Der CPC baut sein Bild leider nicht von oben nach unten oder umgekehrt auf, sondern baut immer jede 8te Zeile auf)

Deshalb auch viel umständlicher Code für einen DAU wie mich (Ich habe mir JAVA ohne Handbuch oder Kurs beigebracht. Einfach 'Learning by doing')

Das Resultat ist allerdings genial geworden.

Hier mal ein Video, wie ich ein komplettes Bild in nur wenigen Minuten erstelle, auf DSK (Diskimage) speichere und es wieder in den (emulierten) Computer lade: (Am Ende kann man auch den "scheibchenweisen" Aufbau des CPC Bildes sehen)

Demonstrations-Video

Geschrieben

Hier ist das vorläufige Fenster des Paint-Programmes:

paint3.png

Komischerweise kommt es manchmal noch zu Fehlfarben...

Wenn mir hier jemand helfen mag, bitte melden.

Ich muss 3 Modi unterstützen:

0 - 16 aus 27 Farben

1 - 4 aus 27 Farben

2 - 2 aus 27 Farben

Irgendwie funktioniert meine Farbberechnung leider noch nicht so, wie ich das möchte.

Mode 0 funktioniert allerdings ganz gut schon.

Geschrieben (bearbeitet)

Eins aber:

Das, was auf dem Display erscheint, ist kein "Bild", wie man es kennt, also kein Bitmap. Es besteht aus tausenden von Bildschirmpixeln (160x200 um es genau zu nehmen)

Aber sicher ist das auch eine Bitmap.

Ich muss also sehr mühevoll ein Bild in seine Pixel zerlegen und dann auch noch an die richtigen Adressen POKEn (Der CPC baut sein Bild leider nicht von oben nach unten oder umgekehrt auf, sondern baut immer jede 8te Zeile auf)

Das ist eine architekturabhängige Eigenart, die aber keinen Einfluss auf die Farbwandlung hat.

Bearbeitet von Bubble
Geschrieben

Stimmt.

Ich habe mir nun einen Wolf gegoogelt.

Wer kann mir sagen, wie ich ein neues BufferedImage erzeugen kann?

Und zwar brauche ich etwas wie:

public BufferedImage convert(BufferedImage input){

    BufferedImage output = new BufferedImage(640,400,BufferedImage.TYPE_INT_RGB);

    // Palette Colours enthält die vorgegebenen Farben

    int anzahl_der_farben = colours.getLength();

      for (int i = 0; i < anzahl_der_farben; i++){


         // konvertiere input zu output

      }

    return output;

}

Wobei colours[] die einzelnen Color(RR,GG,BB) enthalten würde, welche verwendet werden dürfen.

Genau das ist, was ich hier brauche.

Nur wie gesagt: Bei Google hab ich nicht viel hilfreiches gefunden.

Auch die JavaDOCs sind leider sehr unglücklich gestaltet.

Wäre also super, wenn mir jemand so einen Code zeigen könnte.

Geschrieben (bearbeitet)

Das Programm läuft nun zu 98%.

Ich habe die Farbreduzierung mit Arrays erstellt, wo eine Farbe mit der nächstmöglichen Farbe verglichen wird. (Ist ja nicht so schwer, bei nur 27 vordefinierten Farben)

Der Vorteil des Arrays ist, dass es blitzschnell geht.

Maximale Renderdauer eines Bildes liegt bei ca. 2-3 Sekunden, wenn das Bild wirklich gross ist.

Normalfall: < 0,5 Sekunden.

Hier mal eine GIF-Animation, welche veranschaulicht, wie im Bruchteil von Sekunden das Bild umgewandelt wird, und wie man es dann noch weiterbearbeiten kann:

paint.gif

Edit:

Übrigens ist das Resultat nach jeder "Aktion" kein neu gerendertes Bild, sondern der direkte Inhalt des Screen-Rams des emulierten Computers. Man sieht das Bild also gleichzeitig im Emulator, wie es entsteht.

Bearbeitet von Devilmarkus
Geschrieben

Hallo,

Dir scheint nur Basiswissen zu fehlen (siehe Array).

Vermutlich hilft dir die Java-Insel am besten weiter:

Java ist auch eine Insel - Programmieren für die Java 2-Plattform in der Version 5 - 5. Auflage - Galileo Computing - ISBN 3-89842-747-1

Da steht auch drin, wie man ein BufferedImage benutzt, wie man Array sortiert und auch "umdreht" (reverse).

GZ zum schicken Programm.

Könntest Du mir auch noch erklären, wofür man soetwas benötigt?

CPC scheint mir schon etwas älter zu sein.

mfg KhanQ

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...