Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

[Geloest]RGBToIndex

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 26.02.2010, 19:17    Titel: [Geloest]RGBToIndex Antworten mit Zitat

Ich hab seit einigen Wochen mal wieder einj kleines Projekt angefangen und hab ein ziemlichen haenger...

Ich braeuchte mal dringenden Rat zu moeglichkeiten und methoden um RGB Bilder in 256 Indexfarben yu berechnen...

Hab schon die 3-3-2bits variante durch und diverse varianten die auf anyahl farben und helligkeitswerte basieren, mit eher maessigem erfolg, meine vorstellung ist eine 'optimierte#n indexierung wie eine umwandlung mit einem grafikprogramm, farben und bild sollen eben so aenhlich wie moeglich am original sein.

Ziel soll spaeter sein ein 24/32bit Image in eine 8bit GIF zu speichern...

gruss

Edit:
Hat 'ne weile gedauert den Algo zu verstehen aber ist nun abgehakt...
_________________


Zuletzt bearbeitet von Eternal_pain am 06.03.2010, 11:15, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 26.02.2010, 19:50    Titel: Antworten mit Zitat

möchtest du so ne musterung dabei bekommen wie das bei paint passiert zB, wenn die farbe nicht so sonderlich gut approximiert werden konnte?


so wie die graue fläche hier: http://www.iupui.edu/~webtrain/images/tutorial_images/ppt_custom_color_scheme.gif

wenn man genau hin sieht merkt man dass das dunkelgrau und hellgrau gemustert ist, und nicht einheitliches mittelgrau
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 26.02.2010, 19:55    Titel: Antworten mit Zitat

MisterD hat Folgendes geschrieben:
möchtest du so ne musterung dabei bekommen

http://de.wikipedia.org/wiki/Dithering_%28Bildbearbeitung%29 lächeln
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 26.02.2010, 19:59    Titel: Antworten mit Zitat

verlink halt wenigstens den englischen.. 200x umfangreicher as usual
http://en.wikipedia.org/wiki/Dither
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 27.02.2010, 00:40    Titel: Antworten mit Zitat

An Dithering hab ich eher nicht gedacht, ywar kann man damit unter umstaenden wohl sicherlich gute ergebnisse erziehlen, hab meine 'Handarbeiten' bisher aber im Grafikprogramm ohne Dithering reduziert... ich guck mal ob ichs irgendwie schaff mal was aufs notebook zu ziehen um ein paar meiner versuche zu zeigen die ungefaehr wohl klar machen was und wie ichs vor hatte, denke jedoch das es dafuer sowas wie eine 'PATENTLOESUNG' gibt... sowas wie eine einheitliche berechnung... bit der 3-3-2 methode bekomme ich kein besonders ansehnliches ergebniss, da wird bspw ein bild mit weit ueber 800000 farben ueberwiegend blautoenen zu 85 indexfarben reduziert die uebergaenge sind schlicht zu hart...
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 27.02.2010, 02:57    Titel: Antworten mit Zitat

FreeImage hat jede Menge Konvertierungsfunktionen mit an Bord. Ein Versuch wäre es bestimmt wert.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 27.02.2010, 14:15    Titel: Antworten mit Zitat

Hi, ich denke FreeImage kann das sicherlich, ist aber nicht das was ich will, ich moechte schlicht keine anderen libs nutzen, haette mich sonst nicht ewig mit LZW und LZ77 kompressionen rumgeschlagen happy

hier is mal einer meiner ansaetze.. sieht prinzipiel auf den ersten blick ganz gut aus, was die uebergaenge angeht allerdings sind die farben leicht verfaelscht.....

Code:

Function ColorCount (byval Image as any ptr) as UInteger   
    If Image=0 Then Return 0

    Dim BufferVersion as UInteger=Peek(UInteger,Image)
   
    If BufferVersion<>7 Then Return 0
   
    Dim BufferBPP     as UInteger=Peek(UInteger,Image+4)
    Dim BufferSizeX   as UInteger=Peek(UInteger,Image+8)
    Dim BufferSizeY   as UInteger=Peek(UInteger,Image+12)
   
    Dim BufferPitch   as UInteger=Peek(UInteger,Image+16)

    Dim ColorBitList as UByte ptr=Callocate(2097152)
   
    Dim CBLByte as UInteger
    Dim CBLBit  as UByte

    Dim IndexColor as UInteger
    Dim CountColor as UInteger
   
    For Y as UInteger=0 to BufferSizeY-1
    For X as UInteger=0 to BufferSizeX-1
       
        Select Case as Const BufferBPP
            Case 1
                IndexColor=Peek (Ubyte ,Image+32+(X*BufferBPP)+(Y*BufferPitch))
            Case 2
                IndexColor=Peek (UShort ,Image+32+(X*BufferBPP)+(Y*BufferPitch))
            Case Else
                IndexColor=Peek (UInteger ,Image+32+(X*BufferBPP)+(Y*BufferPitch)) and &h00FFFFFF
        End Select
                   
        CBLByte = Fix(IndexColor/8)
        CBLBit  = (IndexColor mod 8)
       
        If Bit(ColorBitList[CBLByte],CBLBit)=0 Then
            CountColor+=1
            ColorBitList[CBLByte]+=(1 SHL CBLBit)
        End If
           
    Next X
    Next Y
   
    Deallocate (ColorBitList)
   
    Return CountColor
End Function

Sub RGBToIndex (Byref Image as any ptr)
     If Image=0 Then Exit Sub
    Dim ImageVersion as UInteger=Peek(UInteger,Image)
     If ImageVersion <> &h07 Then Exit Sub
    Dim ImageBPP     as UInteger=Peek(UInteger,Image+4)
     If ImageBPP      < &h03 Then Exit Sub
    Dim Imagewidth   as UInteger=Peek(UInteger,Image+8)
    Dim Imageheight  as UInteger=Peek(UInteger,Image+12)
    Dim Imagepitch   as UInteger=Peek(UInteger,Image+16)
   
    'Step1
    Dim ReadColor as UInteger
   
    Dim IndexMap    as UInteger PTR=Callocate(16)
    Dim IndexBitMap as UByte Ptr Ptr=Callocate(16)
        IndexBitMap[0]=Callocate(24)
        IndexBitMap[1]=Callocate(24)
        IndexBitMap[2]=Callocate(24)
        IndexBitMap[3]=Callocate(24)
        Dim IBMByte as Integer
        Dim IBMBit  as Integer
   
    Dim RRed   as Integer
    Dim RGreen as Integer
    Dim RBlue  as Integer
    Dim RH     as Integer
   
    For Y as UInteger=0 to Imageheight-1
    For X as UInteger=0 to Imagewidth-1
        ReadColor=Peek(UInteger,Image+32+(X*ImageBPP)+(Y*Imagepitch))
       
        RRed   = Lobyte(Hiword(ReadColor))
        RGreen = Hibyte(Loword(ReadColor))
        RBlue  = Lobyte(Loword(ReadColor))
        RH     = (RRed+RGreen+RBlue)/3
       
        If RH>31 and RH<224 Then
            RH=IIF(RH-64 < 0,0,RH-64)
            IBMByte = Fix(RH/8)
            IBMBit  = (RH mod 8)

            If     RRed   > RGreen and RRed   >= RGreen Then
                If Bit(IndexBitMap[0][IBMByte],IBMBit)=0 Then
                    IndexMap[0]+=1
                    IndexBitMap[0][IBMByte]+=(1 SHL IBMBit)
                End If
            ElseIf RGreen > RBlue  and RGreen >= RRed   Then
                If Bit(IndexBitMap[1][IBMByte],IBMBit)=0 Then
                    IndexMap[1]+=1
                    IndexBitMap[1][IBMByte]+=(1 SHL IBMBit)
                End If
            ElseIf RBlue  > RRed   and RBlue  >= RGreen Then
                If Bit(IndexBitMap[2][IBMByte],IBMBit)=0 Then
                    IndexMap[2]+=1
                    IndexBitMap[2][IBMByte]+=(1 SHL IBMBit)
                End If
            ElseIf RRed   = RGreen and RGreen  = RBlue  Then
                If Bit(IndexBitMap[3][IBMByte],IBMBit)=0 Then
                    IndexMap[3]+=1
                    IndexBitMap[3][IBMByte]+=(1 SHL IBMBit)
                End If
            End If
        End If
    Next X
    Next Y

    Dim IBMCRed    as UByte Ptr=Callocate(192)
    Dim IBMCRedC   as UByte
    Dim IBMCGreen  as UByte Ptr=Callocate(192)
    Dim IBMCGreenC as UByte
    Dim IBMCBlue   as UByte Ptr=Callocate(192)
    Dim IBMCBlueC  as UByte
    Dim IBMCGrey   as UByte Ptr=Callocate(192)
    Dim IBMCGreyC  as UByte
   
    For IBMC as UInteger=0 to 191
        IBMByte = Fix(IBMC/8)
        IBMBit  = (IBMC mod 8)
       
        IBMCRed[IBMC]  =IBMCRedC
        IBMCGreen[IBMC]=IBMCGreenC
        IBMCBlue[IBMC] =IBMCBlueC
        IBMCGrey[IBMC] =IBMCGreyC
       
        If Bit(IndexBitMap[0][IBMByte],IBMBit) Then IBMCRedC   += 1
        If Bit(IndexBitMap[1][IBMByte],IBMBit) Then IBMCGreenC += 1
        If Bit(IndexBitMap[2][IBMByte],IBMBit) Then IBMCBlueC  += 1
        If Bit(IndexBitMap[3][IBMByte],IBMBit) Then IBMCGreyC  += 1
    Next IBMC
   
    Deallocate (IndexBitMap[3])
    Deallocate (IndexBitMap[2])
    Deallocate (IndexBitMap[1])
    Deallocate (IndexBitMap[0])
    Deallocate (IndexBitMap)
   
   
    Dim IndexPMap as Double=(IndexMap[0]+IndexMap[1]+IndexMap[2]+IndexMap[3])/254
   
    Dim IndexPRed   as Integer=1
    Dim IndexPGreen as Integer=IndexPRed   + (IndexMap[0]/IndexPMap)
    Dim IndexPBlue  as Integer=IndexPGreen + (IndexMap[1]/IndexPMap)
    Dim IndexPGrey  as Integer=IndexPBlue  + (IndexMap[2]/IndexPMap)


    '?IndexPRed,IndexMap[0],191/IndexMap[0]/IndexPMap
    '?IndexPGreen,IndexMap[1],IndexMap[1]/IndexPMap
    '?IndexPBlue,IndexMap[2],IndexMap[2]/IndexPMap
    '?IndexPGrey,IndexMap[3],IndexMap[3]/IndexPMap

    'Step2
    Dim HighColorMap  as Ubyte PTR=Callocate(2097152)
    Dim IndexColorMap as UByte PTR=Callocate(32)

    Dim HCMByte as Integer
    Dim HCMBit  as Integer

    Dim ICMByte as Integer
    Dim ICMBit  as Integer
   
    Dim PrePal  as UInteger Ptr=Callocate(256*4)
       
    Dim Index   as Integer
   
    Dim MRed   as Integer
    Dim MGreen as Integer
    Dim MBlue  as Integer
   
    Dim WriteColor as UInteger
   
    For Y as UInteger=0 to Imageheight-1
    For X as Uinteger=0 to Imagewidth-1
        ReadColor=Peek(UInteger,Image+32+(X*ImageBPP)+(Y*Imagepitch)) and &h00FFFFFF
       
        HCMByte =Fix(ReadColor/8)
        HCMBit  =(ReadColor mod 8)
       
        RRed   = Lobyte(Hiword(ReadColor))
        RGreen = Hibyte(Loword(ReadColor))
        RBlue  = Lobyte(Loword(ReadColor))
        RH     = (RRed+RGreen+RBlue)/3
         
       
        If Bit(HighColorMap[HCMByte],HCMBit)=0 Then
       
            HighColorMap[HCMByte]+=(1 SHL HCMBit)
       
'           If RH<128 Then
'               RRed   = IIF(RRed   -5 < 0, 0, RRed   -5)
'               RGreen = IIF(RGreen -5 < 0, 0, RGreen -5)
'               RBlue  = IIF(RBlue  -5 < 0, 0, RBlue  -5)
'           Else
'               RRed   = IIF(RRed   +5 > 255, 255, RRed   +5)
'               RGreen = IIF(RGreen +5 > 255, 255, RGreen +5)
'               RBlue  = IIF(RBlue  +5 > 255, 255, RBlue  +5)
'           End If
           
            WriteColor=RGB(RRed,RGreen,RBlue)
           
            If RH>31 and RH<224 Then
                RH=IIF(RH-64 < 0,0,RH-64)
           
                If RRed>RGreen and RRed >=RBlue Then
                    Index=IndexPRed   + (IBMCRed[RH] / (IBMCRedC/(IndexMap[0]/IndexPMap)))
                    RRed   = IIF(RRed   +10 > 255, 255, RRed   +10)
                    If RRed=RBlue Then RBlue  = IIF(RBlue  +10 > 255, 255, RBlue  +10)
                   
                ElseIf RGreen>RBlue and RGreen>=RRed Then
                    Index=IndexPGreen + (IBMCGreen[RH] / (IBMCGreenC/(IndexMap[1]/IndexPMap)))
                    RGreen = IIF(RGreen +10 > 255, 255, RGreen +10)
                    If RGreen=RRed Then RRed   = IIF(RRed   +10 > 255, 255, RRed   +10)
                   
                ElseIf RBlue>RRed and RBlue>=RGreen Then
                    Index=IndexPBlue  + (IBMCBlue[RH] / (IBMCBlueC/(IndexMap[2]/IndexPMap)))                   
                    RBlue  = IIF(RBlue  +10 > 255, 255, RBlue  +10)
                    If RBlue=RGreen Then RGreen = IIF(RGreen +10 > 255, 255, RGreen +10)
                       
                ElseIf RRed=RGreen and RGreen=RBlue Then
                    Index=IndexPGrey  + (IBMCGrey[RH] / (IBMCGreyC/(IndexMap[3]/IndexPMap)))
                End If
            Else
                Index=IIF(RH<32,0,255)
            End If
           
            ICMByte=Fix(Index/8)
            ICMBit =(Index mod 8)
           
            If Bit(IndexColorMap[ICMByte],ICMBit)=0 Then
                IndexColorMap[ICMByte]+=(1 SHL ICMBit)
               
                If Index>0 and Index<255 Then
                    PrePal[Index]=WriteColor
                Else
                    PrePal[Index]=RGB(Index,Index,Index)
                End If
               
            Else
                MRed   = Lobyte(Hiword(PrePal[Index]))
                MGreen = Hibyte(Loword(PrePal[Index]))
                MBlue  = Lobyte(Loword(PrePal[Index]))
               
                    PrePal[Index]=RGB( ((RRed+MRed)/2), ((RGreen+MGreen)/2), ((RBlue+MBlue)/2))
            End If
        End If
    Next X
    Next Y

   
    'Step3
    For Y as UInteger=0 to Imageheight-1
    For X as Uinteger=0 to Imagewidth-1
        ReadColor=Peek(UInteger,Image+32+(X*ImageBPP)+(Y*Imagepitch))
       
        RRed   = Lobyte(Hiword(ReadColor))
        RGreen = Hibyte(Loword(ReadColor))
        RBlue  = Lobyte(Loword(ReadColor))
        RH     = (RRed+RGreen+RBlue)/3
           
        If RH>31 and RH<224 Then
            RH=IIF(RH-64 < 0,0,RH-64)
           
                If RRed>RGreen and RRed >=RBlue Then
                    Index=IndexPRed   + (IBMCRed[RH] / (IBMCRedC/(IndexMap[0]/IndexPMap)))
                ElseIf RGreen>RBlue and RGreen>=RRed Then
                    Index=IndexPGreen + (IBMCGreen[RH] / (IBMCGreenC/(IndexMap[1]/IndexPMap)))
                ElseIf RBlue>RRed and RBlue>=RGreen Then
                    Index=IndexPBlue  + (IBMCBlue[RH] / (IBMCBlueC/(IndexMap[2]/IndexPMap)))                   
                ElseIf RRed=RGreen and RGreen=RBlue Then
                    Index=IndexPGrey  + (IBMCGrey[RH] / (IBMCGreyC/(IndexMap[3]/IndexPMap)))
                End If
            Else
                Index=IIF(RH<32,0,255)
        End If
       
        Poke UInteger,Image+32+(X*ImageBPP)+(Y*Imagepitch),PrePal[Index]
       
    Next X
    Next Y
   
    Put (0,0),image
/'
    dim cx as integer
    dim cy as integer
   
    for l as integer=0 to 255
        line (341+(cx*20),1+(cy*20))-(359+(cx*20),19+(cy*20)),PrePal[l],bf
       
        'If l>=IndexPRed and l<IndexPGreen Then
        'or l=IndexPGreen or l=IndexPBlue or l=IndexPGrey Then
        '    line (340+(cx*20),0+(cy*20))-(360+(cx*20),20+(cy*20)),&hFFFFFF,b
        'End if
       
        cx+=1
        If cx=16 then cx=0:cy+=1
    next l
'/       
End Sub

#Include "[Function]TextureLoad.bi"
Screen 19,32

Dim Test as any ptr
Test=TextureLoad("universe.bmp")
RGBToIndex(Test)
'Put (0,0),test
?ColorCount(Test)

sleep



textureload einfach duch laden einer bitmap ersetzen
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 01.03.2010, 07:01    Titel: Antworten mit Zitat

weiss evtl jemand ein paar links zu diesem Thema?
Da die meisten Grafikprogramme diese Funktion haben muesste es doch irgendwo auch eine brauchbare referenz dafuer geben, habe mit google bisher leider noch nichts brauchbares gefunden...
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 01.03.2010, 14:41    Titel: Antworten mit Zitat

Schau doch einfach in den Freeimage Sourcecode, und lass dich ... inspirieren zwinkern
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 03.03.2010, 13:11    Titel: Antworten mit Zitat

nach ewigen Googlen und Lesen und leider wenig verstehen der Unterschiedlichsten Farbmodelle und Algorithmen hab ich endlich ansatzweise gefunden was ich suchte....

Hier koennte ich ein wenig Hilfe bei der uebersetzung gebrauchen da ich leider nicht alles ganz verstehe...
Der Code ist java...

Hier noch ein paar hilfreiche erklaerende links zur Theorie des Themas

http://www.it.fht-esslingen.de/~schmidt/vorlesungen/mm/seminar/ss00/HTML/node200.html

http://en.literateprograms.org/Median_cut_algorithm_(C_Plus_Plus)


Code:


package ij.process;

import java.awt.*;
import java.awt.image.*;
import ij.*; //??

/** Converts an RGB image to 8-bit index color using Heckbert's median-cut
    color quantization algorithm. Based on median.c by Anton Kruger from the
    September, 1994 issue of Dr. Dobbs Journal.
*/
public class MedianCut {
   
    static final int MAXCOLORS = 256;   // maximum # of output colors
    static final int HSIZE = 32768;     // size of image histogram
    private int[] hist;                 // RGB histogram and reverse color lookup table
    private int[] histPtr;              // points to colors in "hist"
    private Cube[] list;                // list of cubes
    private int[] pixels32;
    private int width, height;
    private IndexColorModel cm;

    public MedianCut(int[] pixels, int width, int height) {
        int color16;

        pixels32 = pixels;
        this.width = width;
        this.height = height;
       
        //build 32x32x32 RGB histogram
        IJ.showProgress(0.3);
        IJ.showStatus("Building 32x32x32 RGB histogram");
        hist = new int[HSIZE];
        for (int i=0; i<width*height; i++) {
            color16 = rgb(pixels32[i]);
            hist[color16]++;
        }
    }
   
    public MedianCut(ColorProcessor ip) {
        this((int[])ip.getPixels(), ip.getWidth(), ip.getHeight());
    }
   
    int getColorCount() {
        int count = 0;
        for (int i=0; i<HSIZE; i++)
            if (hist[i]>0) count++;
        return count;
    }
   

    Color getModalColor() {
        int max=0;
        int c = 0;
        for (int i=0; i<HSIZE; i++)
            if (hist[i]>max) {
                max = hist[i];
                c = i;
            }
        return new Color(red(c), green(c), blue(c));
    }
   

    // Convert from 24-bit to 15-bit color
    private final int rgb(int c) {
        int r = (c&0xf80000)>>19;
        int g = (c&0xf800)>>6;
        int b = (c&0xf8)<<7;
        return b | g | r;
    }
   
    // Get red component of a 15-bit color
    private final int red(int x) {
        return (x&31)<<3;
    }
   
    // Get green component of a 15-bit color
    private final int green(int x) {
        return (x>>2)&0xf8;
    }
   
    // Get blue component of a 15-bit color
    private final int blue(int x) {
        return (x>>7)&0xf8;
    }


    /** Uses Heckbert's median-cut algorithm to divide the color space defined by
    "hist" into "maxcubes" cubes. The centroids (average value) of each cube
    are are used to create a color table. "hist" is then updated to function
    as an inverse color map that is used to generate an 8-bit image. */
    public Image convert(int maxcubes) {
        ImageProcessor ip = convertToByte(maxcubes);
        return ip.createImage();
    }

    /** This is a version of convert that returns a ByteProcessor. */
    public ImageProcessor convertToByte(int maxcubes) {
        int lr, lg, lb;
        int i, median, color;
        int count;
        int k, level, ncubes, splitpos;
        int num, width;
        int longdim=0;  //longest dimension of cube
        Cube cube, cubeA, cubeB;
       
        // Create initial cube
        IJ.showStatus("Median cut");
        list = new Cube[MAXCOLORS];
        histPtr = new int[HSIZE];
        ncubes = 0;
        cube = new Cube();
        for (i=0,color=0; i<=HSIZE-1; i++) {
            if (hist[i] != 0) {
                histPtr[color++] = i;
                cube.count = cube.count + hist[i];
            }
        }
        cube.lower = 0; cube.upper = color-1;
        cube.level = 0;
        Shrink(cube);
        list[ncubes++] = cube;

        //Main loop
        while (ncubes < maxcubes) {

            // Search the list of cubes for next cube to split, the lowest level cube
            level = 255; splitpos = -1;
            for (k=0; k<=ncubes-1; k++) {
                if (list[k].lower == list[k].upper) 
                    ;   // single color; cannot be split
                else if (list[k].level < level) {
                    level = list[k].level;
                    splitpos = k;
                }
            }
            if (splitpos == -1) // no more cubes to split
                break;

            // Find longest dimension of this cube
            cube = list[splitpos];
            lr = cube.rmax - cube.rmin;
            lg = cube.gmax - cube.gmin;
            lb = cube.bmax - cube.bmin;
            if (lr >= lg && lr >= lb) longdim = 0;
            if (lg >= lr && lg >= lb) longdim = 1;
            if (lb >= lr && lb >= lg) longdim = 2;
           
            // Sort along "longdim"
            reorderColors(histPtr, cube.lower, cube.upper, longdim);
            quickSort(histPtr, cube.lower, cube.upper);
            restoreColorOrder(histPtr, cube.lower, cube.upper, longdim);

            // Find median
            count = 0;
            for (i=cube.lower;i<=cube.upper-1;i++) {
                if (count >= cube.count/2) break;
                color = histPtr[i];
                count = count + hist[color];
            }
            median = i;

            // Now split "cube" at the median and add the two new
            // cubes to the list of cubes.
            cubeA = new Cube();
            cubeA.lower = cube.lower;
            cubeA.upper = median-1;
            cubeA.count = count;
            cubeA.level = cube.level + 1;
            Shrink(cubeA);
            list[splitpos] = cubeA;             // add in old slot

            cubeB = new Cube();
            cubeB.lower = median;
            cubeB.upper = cube.upper;
            cubeB.count = cube.count - count;
            cubeB.level = cube.level + 1;
            Shrink(cubeB);
            list[ncubes++] = cubeB;             // add in new slot */
            if (ncubes%15==0)
                IJ.showProgress(0.3 + (0.6*ncubes)/maxcubes);
        }

        // We have enough cubes, or we have split all we can. Now
        // compute the color map, the inverse color map, and return
        // an 8-bit image.
        IJ.showProgress(0.9);
        makeInverseMap(hist, ncubes);
        IJ.showProgress(0.95);
        return makeImage();
    }
   
    void Shrink(Cube cube) {
    // Encloses "cube" with a tight-fitting cube by updating the
    // (rmin,gmin,bmin) and (rmax,gmax,bmax) members of "cube".

        int r, g, b;
        int color;
        int rmin, rmax, gmin, gmax, bmin, bmax;

        rmin = 255; rmax = 0;
        gmin = 255; gmax = 0;
        bmin = 255; bmax = 0;
        for (int i=cube.lower; i<=cube.upper; i++) {
            color = histPtr[i];
            r = red(color);
            g = green(color);
            b = blue(color);
            if (r > rmax) rmax = r;
            if (r < rmin) rmin = r;
            if (g > gmax) gmax = g;
            if (g < gmin) gmin = g;
            if (b > bmax) bmax = b;
            if (b < bmin) bmin = b;
        }
        cube.rmin = rmin; cube.rmax = rmax;
        cube.gmin = gmin; cube.gmax = gmax;
        cube.bmin = bmin; cube.bmax = bmax;
    }


    void makeInverseMap(int[] hist, int ncubes) {
    // For each cube in the list of cubes, computes the centroid
    // (average value) of the colors enclosed by that cube, and
    // then loads the centroids in the color map. Next loads
    // "hist" with indices into the color map

        int r, g, b;
        int color;
        float rsum, gsum, bsum;
        Cube cube;
        byte[] rLUT = new byte[256];
        byte[] gLUT = new byte[256];
        byte[] bLUT = new byte[256];

        IJ.showStatus("Making inverse map");
        for (int k=0; k<=ncubes-1; k++) {
            cube = list[k];
            rsum = gsum = bsum = (float)0.0;
            for (int i=cube.lower; i<=cube.upper; i++) {
                color = histPtr[i];
                r = red(color);
                rsum += (float)r*(float)hist[color];
                g = green(color);
                gsum += (float)g*(float)hist[color];
                b = blue(color);
                bsum += (float)b*(float)hist[color];
            }

            // Update the color map
            r = (int)(rsum/(float)cube.count);
            g = (int)(gsum/(float)cube.count);
            b = (int)(bsum/(float)cube.count);
            if (r==248 && g==248 && b==248)
                r=g=b=255;  // Restore white (255,255,255)
            rLUT[k] = (byte)r;
            gLUT[k] = (byte)g;
            bLUT[k] = (byte)b;
        }
        cm = new IndexColorModel(8, ncubes, rLUT, gLUT, bLUT);
       
        // For each color in each cube, load the corre-
        // sponding slot in "hist" with the centroid of the cube.
        for (int k=0; k<=ncubes-1; k++) {
            cube = list[k];
            for (int i=cube.lower; i<=cube.upper; i++) {
                color = histPtr[i];
                hist[color] = k;
            }
        }
    }
   

    void reorderColors(int[] a, int lo, int hi, int longDim) {
    // Change the ordering of the 5-bit colors in each word of int[]
    // so we can sort on the 'longDim' color
   
        int c, r, g, b;
        switch (longDim) {
            case 0: //red
                for (int i=lo; i<=hi; i++) {
                    c = a[i];
                    r = c & 31;
                    a[i] = (r<<10) | (c>>5);
                    }
                break;
            case 1: //green
                for (int i=lo; i<=hi; i++) {
                    c = a[i];
                    r = c & 31;
                    g = (c>>5) & 31;
                    b = c>>10;
                    a[i] = (g<<10) | (b<<5) | r;
                    }
                break;
            case 2: //blue; already in the needed order
                break;
        }
    }
   

    void restoreColorOrder(int[] a, int lo, int hi, int longDim) {
    // Restore the 5-bit colors to the original order
   
        int c, r, g, b;
        switch (longDim){
            case 0: //red
                for (int i=lo; i<=hi; i++) {
                    c = a[i];
                    r = c >> 10;
                    a[i] = ((c&1023)<<5) | r;
                }
                break;
            case 1: //green
                for (int i=lo; i<=hi; i++) {
                    c = a[i];
                    r = c & 31;
                    g = c>>10;
                    b = (c>>5) & 31;
                    a[i] = (b<<10) | (g<<5) | r;
                }
                break;
            case 2: //blue
                break;
        }
    }
   
   
    void quickSort(int a[], int lo0, int hi0) {
   // Based on the QuickSort method by James Gosling from Sun's SortDemo applet
   
      int lo = lo0;
      int hi = hi0;
      int mid, t;

      if ( hi0 > lo0) {
         mid = a[ ( lo0 + hi0 ) / 2 ];
         while( lo <= hi ) {
            while( ( lo < hi0 ) && ( a[lo] < mid ) )
               ++lo;
            while( ( hi > lo0 ) && ( a[hi] > mid ) )
               --hi;
            if( lo <= hi ) {
              t = a[lo];
              a[lo] = a[hi];
              a[hi] = t;
               ++lo;
               --hi;
            }
         }
         if( lo0 < hi )
            quickSort( a, lo0, hi );
         if( lo < hi0 )
            quickSort( a, lo, hi0 );

      }
   }


    ImageProcessor makeImage() {
    // Generate 8-bit image
   
        Image img8;
        byte[] pixels8;
        int color16;
       
        IJ.showStatus("Creating 8-bit image");
        pixels8 = new byte[width*height];
        for (int i=0; i<width*height; i++) {
            color16 = rgb(pixels32[i]);
            pixels8[i] = (byte)hist[color16];
        }
        ImageProcessor ip = new ByteProcessor(width, height, pixels8, cm);
        IJ.showProgress(1.0);
        return ip;
    }
   
   
} //class MedianCut


class Cube {            // structure for a cube in color space
    int  lower;         // one corner's index in histogram
    int  upper;         // another corner's index in histogram
    int  count;         // cube's histogram count
    int  level;         // cube's level
    int  rmin, rmax;
    int  gmin, gmax;
    int  bmin, bmax;
   
    Cube() {
        count = 0;
    }   

    public String toString() {
        String s = "lower=" + lower + " upper=" + upper;
        s = s + " count=" + count + " level=" + level;
        s = s + " rmin=" + rmin + " rmax=" + rmax;
        s = s + " gmin=" + gmin + " gmax=" + gmax;
        s = s + " bmin=" + bmin + " bmax=" + bmax;
        return s;
    }
   
}

_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz