Current Transfer Color (Reduced Color)
###########
# #
# Start #
# #
###########
# gmic i test_image.png +pal srb2 tic rep_transfer_color_reduced[0] [1],.5,3,2,8,8,4,,10,1,1 rm.
# gmic sp cat +pal 56 rep_transfer_color_reduced[0] [1],.5,3,2,8,8,4,0,16,.5,0
# rep_transfer_color_reduced has been completed without ordered dithering.
# TODO: Do ordered dithering.
#@cli rep_transfer_color_reduced:
#@cli : Change images to look as if it was reduced. Can be used to emulate old hardware.
rep_transfer_color_reduced:
skip ${2=0},${3=0},${4=0},${5=0},${6=0},${7=0},${8=0},${9=},${10=.5},${11=0},${12=0}
pass$1 0
if s==2||s>4 error inv_pal_inp fi
use_alpha_remap=0
if narg($9)
number_of_alpha_band={min(max(2,int(abs($9))),255)}
if ($9!=0)&&$number_of_alpha_band<255 use_alpha_remap=1 fi
fi
if $use_alpha_remap
$number_of_alpha_band,1,1,1,"begin(
const rescale=(w-1)/255;
);
x/rescale"
round. 0
_rep_transfer_color_reduced[0--3] [-2],${2-8},[-1],${10-12}
rm.
else
_rep_transfer_color_reduced[^-1] [-1],${2-8},,${10-12}
fi
rm.
_rep_transfer_color_reduced:
skip ${2=0},${3=0},${4=0},${5=0},${6=0},${7=0},${8=0},${9=},${10=.5},${11=0},${12=0}
# color_palette = $1
# color_dither = $2
# pixel_ratio_w,pixel_ratio_h,window_width,window_height,color_restriction_per_window,color_restriction_whole,number_of_alpha,alpha_dithering,alpha_mode,alpha_restrict
pixel_ratio_w,pixel_ratio_h={int(abs([$3,$4]))}
window_width,window_height={int(abs([$5,$6]))}
color_restriction_per_window,color_restriction_whole={v=int(abs($7));v?max(2,v):0;},{v=int(abs($8));v?max(2,v):0}
if $color_restriction_per_window<=$color_restriction_whole color_restriction_per_window=0 fi
dec_color_restriction_whole={$color_restriction_whole-1}
alpha_dithering={cut($10,0,1)}
alpha_mode=${is_image_arg\ $9}
alpha_mode={($11%2)+$alpha_mode}
adj_alpha_map={$alpha_mode?1}
pixel_ratio_gcd={gcd($pixel_ratio_w,$pixel_ratio_h)}
if $pixel_ratio_gcd>1 pixel_ratio_w,pixel_ratio_h/=$pixel_ratio_gcd fi
pass$1 0
activate_window_based_indexing={($color_restriction_per_window<whd#-1)&&($window_width>1||$window_height>1)}
activate_create_restricted_palette={$color_restriction_whole?$color_restriction_whole<whd#-1}
if h#-1>1&&w#-1==1 rotate. 90
elif h#-1>1||d#-1>1 colormap. 0
fi
if s==2||s==4 remove_opacity. fi
if s==1
foreach[^-1] {
if s>2
if s==3 to_gray
else to_graya
fi
fi
}
fi
store. palette_image
if narg($9)&&$alpha_mode
pass$9 0
store. alpha_image
process_alpha=1
alpha_restriction_per_window={$12?min(int(abs($12)),w#-1):$color_restriction_per_window}
else
adj_alpha_map=0
fi
if $pixel_ratio_w==1||$pixel_ratio_h==1
initial_rescale_w,initial_rescale_h={bd=max($pixel_ratio_w,$pixel_ratio_h);100*($pixel_ratio_w>$pixel_ratio_h?vector(#2,1)/[bd,1]:vector(#2,1)/[1,bd])}
else
min_dimension,max_dimension={min($pixel_ratio_w,$pixel_ratio_h)},{max($pixel_ratio_w,$pixel_ratio_h)}
recip_rd={1/($max_dimension/$min_dimension)}
initial_rescale_w,initial_rescale_h={100*($pixel_ratio_w>$pixel_ratio_h?[$recip_rd,1]:[1,$recip_rd])}
fi
foreach {
if s>4 continue fi
$palette_image
num_of_color_chans_in_target_image={!(s#0%2)?(s#0-1):s#0}
dec_num_of_color_chans_in_target_image={$num_of_color_chans_in_target_image-1}
if $num_of_color_chans_in_target_image<s to_gray. fi
use_alpha_map={$adj_alpha_map&&!(s#0%2)}
resize[-2] $initial_rescale_w%,$initial_rescale_h%,100%,100%,3
if $activate_create_restricted_palette
sh[0] 0,$dec_num_of_color_chans_in_target_image
+index[-1] [1],$2,0
histogram. 100%
{w},1,1,1,x
pixelsort. -,x,..
crop. 0,0,$dec_color_restriction_whole,0
map. [-4]
k[0,-1]
fi
if $activate_window_based_indexing
sh[0] 0,$dec_num_of_color_chans_in_target_image
rep_index_by_window_and_color_restriction[-1] [-2],$2,$color_restriction_per_window,$window_width,$window_height,1,1
rm.
if $use_alpha_map
sh[0] {s#0-1}
$alpha_image
if $alpha_mode==2 rep_index_by_window_and_color_restriction[-2] [-1],$2,$alpha_restriction_per_window,$window_width,$window_height,1,1
else index[-2] [-1],$2,1
fi
rm[-2,-1]
fi
else
sh[0] 0,$dec_num_of_color_chans_in_target_image
index[-1] [-2],$2,1
rm.
if $use_alpha_map
sh[0] {s#0-1}
$alpha_image
index[-2] [-1],$2,1
rm[-2,-1]
fi
fi
resize[0] {$pixel_ratio_w*100}%,{$pixel_ratio_h*100}%,100%,100%,1
k[0]
}
###########
# #
# END-FIN #
# #
###########
###########
# #
# Start #
# #
###########
#@cli rep_index_by_window_and_color_restriction:[palette],0<=_dithering<=1,_color_restriction>2,_window_width,_window_height,_window_depth,_map_palette={ 0 | 1 }
#@cli : Index images per window
rep_index_by_window_and_color_restriction:
dithering,col_res,wi_w,wi_h,wi_d,map_palette,timg={cut($2,0,1)},{cut(int(abs($3)),2,w#-1)},{vmax(vector(#3,1),int(abs([${4-6}])))},{$7%2},{$!}
dec_col_res={$col_res-1}
pass$1 1
if h#-1>1&&d#-1==1
rm. pass$1 0
rotate. -90
elif h#-1>1&&d#-1>1
rm. pass$1 0
colormap. 0,,0
fi
if $dithering
# Jarvis, Judice, and Ninke dithering Array
jjn_1R0D,jjn_2R0D,\
jjn_2L1D,jjn_1L1D,jjn_M01D,jjn_1R1D,jjn_2R1D,\
jjn_2L2D,jjn_1L2D,jjn_M02D,jjn_1R2D,jjn_2R2D\
={([7,5,3,5,7,5,3,1,3,5,3,1]/48)*$dithering}
fi
eval "
const spectrum_size=s#-1;
const rf=$timg;
valid_spec=1;
repeat(rf,id,
if(s#id!=spectrum_size,valid_spec=0;break(););
);
valid_spec;
"
if !${} error incompatible_img_pal fi
if $col_res>=w#-1
index[^-1] [-1],$dithering,$map_palette
rm.
return
fi
repeat $timg local[$>,-1]
{
ow,oh,od,tw,th,td,nw,nh,nd={od=[w#0,h#0,d#0];wd=vmin([w#0,h#0,d#0],[$wi_w,$wi_h,$wi_d]);td=ceil(od/wd);nd=td*wd;[od,td,nd]}
if [$tw,$th,$td]==vector(#3,1)
+index[0] [1],1,0
histogram. 100%
{w},1,1,1,x
pixelsort. -,x,..
crop. 0,0,$dec_col_res,0
map. ...
index[0] .,$dithering,$map_palette
else
r[0] $nw,$nh,$nd,100%,0,3,.5,.5,.5
+index[0] [1],{$dithering?.75},0
$tw,$th,$td,1,*"begin(
const nb_cols=w#1;
const spectrum_size=s#1;
const inc_spectrum_size=spectrum_size+1;
const nb_restrict=$col_res;
const dec_nb_restrict=nb_restrict-1;
const res_y_spec=nb_restrict*spectrum_size;
const wi_w=$wi_w;
const wi_h=$wi_h;
const wi_d=$wi_d;
const dec_wi_w=wi_w-1;
const dec_wi_h=wi_h-1;
const dec_wi_d=wi_d-1;
const box_dim=wi_w*wi_h*wi_d;
init_freq_y_ind=expr('(x%2)?int(x/2);',nb_cols*2);
init_sel_res_pal_dist_arr=vector(#nb_restrict,0);
const dithering_mode=$dithering;
const map_palette=$map_palette;
dithering_mode?(
# jjn_1R0D jjn_2R0D
# jjn_2L1D jjn_1L1D jjn_M01D jjn_1R1D jjn_2R1D
# jjn_2L2D jjn_1L2D jjn_M02D jjn_1R2D jjn_2R2D
const jjn_1R0D=$jjn_1R0D;
const jjn_2R0D=$jjn_2R0D;
const jjn_2L1D=$jjn_2L1D;
const jjn_1L1D=$jjn_1L1D;
const jjn_M01D=$jjn_M01D;
const jjn_1R1D=$jjn_1R1D;
const jjn_2R1D=$jjn_2R1D;
const jjn_2L2D=$jjn_2L2D;
const jjn_1L2D=$jjn_1L2D;
const jjn_M02D=$jjn_M02D;
const jjn_1R2D=$jjn_1R2D;
const jjn_2R2D=$jjn_2R2D;
v_col()=I(#2,pos_x,pos_y,pos_z);
# gen_res_pal_col();
map_palette?(
result_img_part()=(
old_color=I(#0,pos_x,pos_y,pos_z);
new_color=I(#1,res_col_id[argmin(sqrt(res_color_sum))],0,0);
I(#0,pos_x,pos_y,pos_z)=new_color;
);
):(
result_img_part()=(
old_color=I(#0,pos_x,pos_y,pos_z);
new_color_pos=res_col_id[argmin(sqrt(res_color_sum))];
new_color=I(#1,new_color_pos,0,0);
i(#0,pos_x,pos_y,pos_z,0)=new_color_pos;
);
);
result_img()=(
result_img_part();
diff_color=old_color-new_color;
use_strip_1D=(pos_y+1)<min_out_of_boundary_offset_pos[2];
use_strip_2D=(pos_y+2)<min_out_of_boundary_offset_pos[2];
use_strip_1D?(
I(#0,pos_x,pos_y+1,pos_z)+=diff_color*jjn_M01D;
);
use_strip_2D?(
I(#0,pos_x,pos_y+2,pos_z)+=diff_color*jjn_M02D;
);
(pos_x-2)>min_out_of_boundary_offset_pos[0]?(
use_strip_1D?(
I(#0,pos_x-2,pos_y+1,pos_z)+=diff_color*jjn_2L1D;
);
use_strip_2D?(
I(#0,pos_x-2,pos_y+2,pos_z)+=diff_color*jjn_2L2D;
);
);
(pos_x-1)>min_out_of_boundary_offset_pos[0]?(
use_strip_1D?(
I(#0,pos_x-1,pos_y+1,pos_z)+=diff_color*jjn_1L1D;
);
use_strip_2D?(
I(#0,pos_x-1,pos_y+2,pos_z)+=diff_color*jjn_1L2D;
);
);
(pos_x+1)<min_out_of_boundary_offset_pos[1]?(
I(#0,pos_x+1,pos_y,pos_z)+=diff_color*jjn_1R0D;
use_strip_1D?(
I(#0,pos_x+1,pos_y+1,pos_z)+=diff_color*jjn_1R1D;
);
use_strip_2D?(
I(#0,pos_x+1,pos_y+2,pos_z)+=diff_color*jjn_1R2D;
);
);
(pos_x+2)<min_out_of_boundary_offset_pos[1]?(
I(#0,pos_x+2,pos_y,pos_z)+=diff_color*jjn_2R0D;
use_strip_1D?(
I(#0,pos_x+2,pos_y+1,pos_z)+=diff_color*jjn_2R1D;
);
use_strip_2D?(
I(#0,pos_x+2,pos_y+2,pos_z)+=diff_color*jjn_2R2D;
);
);
);
):(
v_col()=I(#0,pos_x,pos_y,pos_z);
# gen_res_pal_col();
map_palette?(
result_img()=(
I(#0,pos_x,pos_y,pos_z)=I(#1,res_col_id[argmin(sqrt(res_color_sum))],0,0);
);
):(
result_img()=(
i(#0,pos_x,pos_y,pos_z,0)=res_col_id[argmin(sqrt(res_color_sum))];
);
);
);
);
c_xp=x*wi_w;
c_yp=y*wi_h;
c_zp=z*wi_d;
min_out_of_boundary_offset_pos=[c_xp,c_xp,c_yp]+[-1,wi_w,wi_h];
freq_y_ind=init_freq_y_ind;
tv=crop(#2,c_xp,c_yp,c_zp,0,wi_w,wi_h,wi_d,1);
repeat(box_dim,k,
++freq_y_ind[tv[k]*2];
);
freq_y_ind=sort(freq_y_ind,0,nb_cols,2);
res_col_id=(freq_y_ind)[1,nb_restrict,2];
res_pal=vector(#res_y_spec,0);
repeat(nb_restrict,p,
res_pal_col=I(#1,res_col_id[p],0,0);
repeat(spectrum_size,q,
res_pal[q*nb_restrict+p]=res_pal_col[q];
);
);
repeat(wi_d,oz,
pos_z=c_zp+oz;
repeat(wi_h,oy,
pos_y=c_yp+oy;
repeat(wi_w,ox,
pos_x=c_xp+ox;
res_color_sum=init_sel_res_pal_dist_arr;
v_col=I(#0,pos_x,pos_y,pos_z);
repeat(spectrum_size,k,
res_color_sum+=sqr((res_pal)[k*nb_restrict,nb_restrict]-v_col[k]);
);
result_img();
);
);
);
0;
"
if !$map_palette channels[0] 0 fi
crop[0] {od=[$ow,$oh,$od];op=[$nw,$nh,$nd]-od;[op,vsum(od,op)-1];}
fi
k[0,1]
}
done
rm.
###########
# #
# END-FIN #
# #
###########
###########
# #
# Start #
# #
###########
#@cli +rep_bayer_threshold_map: iteration,normalize
#@cli : Create Bayer Threshold Map
+rep_bayer_threshold_map:
ws=2
(0,2;3,1)
+store. initial_map
repeat $1 {
ws*=2
$initial_map
$ws,$ws
eval[-2] "begin(
const ws=$ws;
const half_ws=ws>>1;
initial=crop(#-3);
);
M_Surface=initial*4;
M_Surface+=i;
draw(#-1,M_Surface,x*half_ws,y*half_ws,0,0,half_ws,half_ws,1,1);
"
rm[-3,-2]
}
###########
# #
# END-FIN #
# #
###########
The bayer matrix thing, well, I’m doing ordered dithering, any assistance could be nice as I have no idea what I’m doing. The matrix works though. See here for details: Ordered dithering - Wikipedia