Originally posted by MadGypsy
View Post

/** MATCH_IMG32_PIXELS_TO_PALETTE * iterate over every pixel of the original image, comparing it to palette entries, until the closest possible entry is found * stores the palette indexes in bytes and returns the bytes * @param bmd - the img32 data to convert * @param lof - level of fogiveness - higher numbers result in less accurate color matches * @param unfind - true|false start a fresh reverse look up dictionary * @return 8 bit bytestreaam of palette indexes */ public static function matchToPalette(bmd:BitmapData, lof:int = 0, unfind:Boolean = false):ByteArray { //determine if we should (re)create the dictionary of matched colors if ((unfind) || (matched == null)) matched = reverseLookUp; //to store the current pixel value of the original image var color:uint; //for storing the individual channels of the image pixel value and the palette value var img_r:uint, pal_r:uint; var img_g:uint, pal_g:uint; var img_b:uint, pal_b:uint; //positioning vars var diff:int, last_diff:int; var pnum:int, index:int = 0; //a container for stored indexes var mip:ByteArray = new ByteArray(); //prime loop iteration var size:int = bmd.width * bmd.height; var pixel:int = -1; //loop compare pixel data while((size - (++pixel)) > 0) { //store original image color color = bmd.getPixel32(pixel%bmd.width, Math.floor(pixel/bmd.width)); //break color down into channels img_r = (color >> 16)& 0xFF; img_g = (color >> 8) & 0xFF; img_b = (color) & 0xFF; //prime offset to absolute max last_diff = 255*3; //if the color has already been found use it if (color in matched) mip.writeByte(matched[color]); else { //loop through the palette comparing and storing the index for the least wrong color and sometimes even the right one for (pnum = 0; pnum < Palette.hexARGB.length; ++pnum) { //break palette color down to channels pal_r = (Palette.hexARGB[pnum] >> 16)& 0xFF; pal_g = (Palette.hexARGB[pnum] >> 8) & 0xFF; pal_b = (Palette.hexARGB[pnum]) & 0xFF; //store the current difference diff = Math.abs(pal_r - img_r) + Math.abs(pal_g - img_g) + Math.abs(pal_b - img_b); //if this diff is smaller, overwrite last_dif and store palette index if (diff < last_diff) { last_diff = diff; index = pnum; } //if the diff is less than the level of forgiveness, quit searching. if (diff <= lof) break; } mip.writeByte(index); //write the alleged best palette index matched[color] = index; //set reverse look-up for this color } } //prime position and return mip.position = 0; return mip; }
//if the color has already been found use it if (color in matched) mip.writeByte(matched[color]); else { //loop through the palette comparing and storing the index for the least wrong color and sometimes even the right one for (pnum = 0; pnum < Palette.hexARGB.length; ++pnum) { //break palette color down to channels pal_r = (Palette.hexARGB[pnum] >> 16)& 0xFF; pal_g = (Palette.hexARGB[pnum] >> 8) & 0xFF; pal_b = (Palette.hexARGB[pnum]) & 0xFF; //find the dominant channel fav_r = ((img_r > img_g) && (img_r > img_b)); fav_g = ((img_g > img_b) && (img_g > img_r)); fav_b = ((img_b > img_r) && (img_b > img_b)); ofs_r = pal_r - img_r; //negative = needs more of this channel ofs_g = pal_g - img_g; // " " " ofs_b = pal_b - img_b; // " " " //if the dominant channel's offset is less than lof, don't store this color regardless of final offset skip = false; if (fav_r && (ofs_r < -lof)) skip = true; if (fav_g && (ofs_g < -lof)) skip = true; if (fav_b && (ofs_b < -lof)) skip = true; //set weight for each channel norm_r = Math.abs(ofs_r) * multiplier.red; norm_g = Math.abs(ofs_g) * multiplier.green; norm_b = Math.abs(ofs_b) * multiplier.blue; //normalize offset diff = norm_r + norm_g + norm_b; //if this diff is smaller, overwrite last_dif and store palette index if ((diff < last_diff) && !skip) { last_diff = diff; index = pnum; } //if the diff is less than the level of forgiveness, quit searching. if (diff <= lof) break; } mip.writeByte(index); //write the alleged best palette index matched[color] = index; //set reverse look-up for this color }
Comment