Devilmarkus Geschrieben 29. September 2009 Geschrieben 29. September 2009 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. Zitieren
Dragon8 Geschrieben 29. September 2009 Geschrieben 29. September 2009 Wie wäre es mit sortieren und dann die ersten 16 Werte des Arrays in ein zweites zu kopieren? Zitieren
flashpixx Geschrieben 29. September 2009 Geschrieben 29. September 2009 Arrays (Java 2 Platform SE v1.4.2) Zitieren
Devilmarkus Geschrieben 30. September 2009 Autor Geschrieben 30. September 2009 *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. Zitieren
Dragon8 Geschrieben 30. September 2009 Geschrieben 30. September 2009 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); } Zitieren
Devilmarkus Geschrieben 30. September 2009 Autor Geschrieben 30. September 2009 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: Zitieren
Devilmarkus Geschrieben 30. September 2009 Autor Geschrieben 30. September 2009 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. Zitieren
flashpixx Geschrieben 30. September 2009 Geschrieben 30. September 2009 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 Zitieren
Bubble Geschrieben 30. September 2009 Geschrieben 30. September 2009 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? Zitieren
Devilmarkus Geschrieben 30. September 2009 Autor Geschrieben 30. September 2009 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. Zitieren
Bubble Geschrieben 30. September 2009 Geschrieben 30. September 2009 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. Zitieren
Devilmarkus Geschrieben 30. September 2009 Autor Geschrieben 30. September 2009 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 Zitieren
Devilmarkus Geschrieben 1. Oktober 2009 Autor Geschrieben 1. Oktober 2009 Hier ist das vorläufige Fenster des Paint-Programmes: 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. Zitieren
Bubble Geschrieben 1. Oktober 2009 Geschrieben 1. Oktober 2009 (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 1. Oktober 2009 von Bubble Zitieren
Devilmarkus Geschrieben 2. Oktober 2009 Autor Geschrieben 2. Oktober 2009 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. Zitieren
Devilmarkus Geschrieben 9. Oktober 2009 Autor Geschrieben 9. Oktober 2009 (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: 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 9. Oktober 2009 von Devilmarkus Zitieren
Khanq Geschrieben 16. Oktober 2009 Geschrieben 16. Oktober 2009 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 Zitieren
Empfohlene Beiträge
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.