|
|
2022/8/11(Thu) 18:30:15|NO.96943
RGBの色をだんだんかえたい
|
|
2022/8/11(Thu) 18:38:49|NO.96944
こうすればいいのでは
repeat
await (1000/60)
r+=1
g+=2
b+=3
if r>255:r=0
if g>255:g=0
if b>255:b=0
redraw 0
pos 0,0
color 255,255,255
boxf
color r,g,b
mes "色は"+r+","+g+","+b+"です"
redraw 1
title "色は"+r+","+g+","+b+"です"
loop
|
|
2022/8/12(Fri) 10:39:51|NO.96951
こんな感じでしょうか
hval=0
repeat
redraw 0
hsvcolor hval,255,255
boxf
redraw
await 17
hval++
if hval>=191:hval=0
loop
|
|
2022/8/13(Sat) 09:18:02|NO.96952
「HSVのH(色相)を変化させることで色を変化させる」という雪月夜さんのアイディアをヒントに、
「読み込んだ画像の色相を変化させるアニメーション」というのをやってみました。
画像を読み込んだあとの加工に時間がかかるので、時間がかかりすぎる場合は
frameの値を減らしたり、shrinkの値を上げたりしてください。
//読み込んだ画像を色相変化させるアニメーション
//参考 https://hooktail.org/computer/index.php?RGB%A4%AB%A4%E9HSV%A4%D8%A4%CE%CA%D1%B4%B9%A4%C8%C9%FC%B8%B5
frame=16 //パターンが1周するまでのコマ数。大きいほどメモリを消費し、加工時間も長くなる。
shrink=2 //1の場合は元画像を縮小せずそのまま扱う。
//2以上に設定した場合は縮小した画像をバッファに置く。メモリと加工時間は節約できるが画質は荒くなる。
loop_t=2000 //1周するのにかかる時間。(ミリ秒単位)
await_t=loop_t/frame
dialog "jpg|jpeg|gif|png|bmp",16
if stat=0 : end
title "0"
buffer 2 : gsel 2 : picload refstr
wid0=ginfo_sx : hei0=ginfo_sy
wid=wid0/shrink : hei=hei0/shrink
buffer 1,wid,hei : gsel 1
pos 0,0 : gzoom wid,hei,2,0,0,wid0,hei0,1
//pset、pgetは遅いのでVRAMを直接読み書きする
vram_wid=(wid*3+3)&0xFFFFFFFC //vramの横一列のバイト数
mref vram,66
//HSVマップの作成
sdim hsvmap,wid*hei*4
dim rgb,3 : dim rgb2,3
repeat hei
cnt0=cnt
vram_add=vram_wid*cnt
repeat wid
x=vram_add+cnt*3
repeat 3
rgb(cnt)=peek(vram,x+cnt) : rgb2(cnt)=rgb(cnt)
loop
sortval rgb2,1 //rgb2(0)はRGBのうち最大の値、rgb(2)は最小の値
sortget maxrgb,0 //maxrgbが0の時はBが、1の時はGが、2の時はRが最大
v=rgb2(0) : min=rgb2(2)
if v : s=255*(v-min)/v : else : s=0
if s { //(v-min)が0の時はsは0になるので、ゼロ除算は回避できる
if maxrgb=2 {
//Rが最大の時
h=60*(rgb(0)-rgb(1))/(v-min)
} else {
if maxrgb=1 {
//Gが最大の時
h=120+60*(rgb(2)-rgb(0))/(v-min)
} else {
//Bが最大の時
h=240+60*(rgb(1)-rgb(2))/(v-min)
}
}
} else {
h=0
}
repeat
if h<0 : h+=360 : else : break
loop
h\=360
x=(cnt0*wid+cnt)*4
wpoke hsvmap,x,h
poke hsvmap,x+2,s
poke hsvmap,x+3,v
loop
loop
//色相を変化させた画像を作成
repeat frame-1,1
await //場合によっては処理に非常に時間がかかることも有りうるので、[x]で途中中断できるようにしておく。
gsel 0 : title str(cnt)
buffer cnt+1,wid,hei : gsel cnt+1
pos 0,0 : gcopy 1,0,0,wid,hei
mref vram,66
h_add=360*cnt/frame
repeat hei
cnt0=cnt
vram_add=vram_wid*cnt
repeat wid
x=(cnt0*wid+cnt)*4
h=(wpeek(hsvmap,x)+h_add)\360
s=peek(hsvmap,x+2)
v=peek(hsvmap,x+3)
//HSVをRGBに変換
if s {
hi=h/60
fn=h-hi*60 //F値の分子。分母は60
m=v-v*s/255
if hi\2 {
//hiが奇数の場合はN値を使う
n=v-v*s*fn/15300 //255*60=15300
if hi=1 {
rgb(2)=n : rgb(1)=v : rgb(0)=m
} else {
if hi=3 {
rgb(2)=m : rgb(1)=n : rgb(0)=v
} else {
rgb(2)=v : rgb(1)=m : rgb(0)=n
}
}
} else {
//hiが偶数の場合はK値を使う
k=v-v*s*(60-fn)/15300
if hi=0 {
rgb(2)=v : rgb(1)=k : rgb(0)=m
} else {
if hi=2 {
rgb(2)=m : rgb(1)=v : rgb(0)=k
} else {
rgb(2)=k : rgb(1)=m : rgb(0)=v
}
}
}
x=vram_add+cnt*3
repeat 3
poke vram,x+cnt,rgb(cnt)
loop
}
loop
loop
loop
dim hsvmap //HSVマップは不要になったのでメモリ解放
screen 0,wid0,hei0 : gsel 0
title ""
//本編
repeat
pos 0,0 : gzoom wid0,hei0,cnt\frame+1,0,0,wid,hei,1
await await_t
loop

| |
|
2022/8/14(Sun) 08:59:50|NO.96956
「待てよ? セーフカラー216色に減色してウィンドウをパレットモードにすれば、
パレットを書き換えるだけで滑らかに色変えができるんじゃ?」
と思い、やってみた結果がこちらになります。
//読み込んだ画像を色相変化させるアニメーション(パレットモード版)
//参考 https://hooktail.org/computer/index.php?RGB%A4%AB%A4%E9HSV%A4%D8%A4%CE%CA%D1%B4%B9%A4%C8%C9%FC%B8%B5
#include "winmm.as"
#const loop_t 2000 //色相が1周するのにかかる時間(ミリ秒単位)
dialog "jpg|jpeg|gif|png|bmp",16
if stat=0 : end
buffer 1 : gsel 1 : picload refstr
wid=ginfo_sx : hei=ginfo_sy
vram_wid1=(wid*3+3)&0xFFFFFFFC //vram(フルカラー)の横一列のバイト数
vram_wid0=(wid+3)&0xFFFFFFFC //vram(パレットモード)の横一列のバイト数
mref vram1,66
screen 0,wid,hei,1 : gsel 0
mref vram0,66
//216色分の基本パレット
sdim paldb,648
repeat 6
cnt0=cnt
repeat 6
cnt1=cnt
repeat 6
x=(cnt0*36+cnt1*6+cnt)*3
poke paldb,x,cnt0*51
poke paldb,x+1,cnt1*51
poke paldb,x+2,cnt*51
loop
loop
loop
//216色分のHSVデータベースの作成
sdim hsvdb,864
dim rgb,3 : dim rgb2,3
repeat 216
x=cnt*4 : y=cnt*3
repeat 3
rgb(cnt)=peek(paldb,y+cnt) : rgb2(cnt)=rgb(cnt)
loop
sortval rgb2,1 //rgb2(0)はRGBのうち最大の値、rgb(2)は最小の値
sortget maxrgb,0 //maxrgbが0の時はRが、1の時はGが、2の時はBが最大
v=rgb2(0) : min=rgb2(2)
if v : s=255*(v-min)/v : else : s=0
if s { //(v-min)が0の時はsは0になるので、ゼロ除算は回避できる
if maxrgb=0 {
//Rが最大の時
h=60*(rgb(2)-rgb(1))/(v-min)
} else {
if maxrgb=1 {
//Gが最大の時
h=120+60*(rgb(0)-rgb(2))/(v-min)
} else {
//Bが最大の時
h=240+60*(rgb(1)-rgb(0))/(v-min)
}
}
} else {
h=0
}
repeat
if h<0 : h+=360 : else : break
loop
h\=360
wpoke hsvdb,x,h
poke hsvdb,x+2,s
poke hsvdb,x+3,v
loop
//減色
title "減色中"
dim bayer,4,4
bayer(0,0)= 3,27, 9,33
bayer(0,1)=39,15,45,21
bayer(0,2)=12,36, 6,30
bayer(0,3)=48,24,42,18
repeat hei
cnt0=cnt
vram_add0=vram_wid0*cnt
vram_add1=vram_wid1*cnt
repeat wid
vram_pos0=vram_add0+cnt
vram_pos1=vram_add1+cnt*3
bay=bayer(cnt\4,cnt0\4)
repeat 3
x=peek(vram1,vram_pos1+2-cnt) //原画のRGB値を取得
//RGB値を0〜5の6段階に変換
y=5
repeat 5
if x<cnt*51+bay : y=cnt : break
loop
rgb(cnt)=y
loop
poke vram0,vram_pos0,rgb(0)*36+rgb(1)*6+rgb(2)
loop
loop
title ""
buffer 1,1,1 : gsel 0 //原画は不要になったのでバッファ解放
mref pal,69 //パレット情報を直接書き込めるようにする
memcpy pal,paldb,648,0,0
//もし減色後の画像に興味があるのなら、以下の/*と*/を削除してみてください。
/*
palette ,,,,1
redraw 1
stop
*/
dim paldb //元のパレットデータベースは不要になったので解放
redraw 1
//本編
repeat
TimeGetTime
h_add=stat\loop_t*360/loop_t
//色相が変化した色を216色分作成
repeat 216
x=cnt*4
s=peek(hsvdb,x+2)
//HSVをRGBに変換
if s {
h=(wpeek(hsvdb,x)+h_add)\360
v=peek(hsvdb,x+3)
hi=h/60
fn=h-hi*60 //F値の分子。分母は60
m=v-v*s/255
if hi\2 {
//hiが奇数の場合はN値を使う
n=v-v*s*fn/15300 //255*60=15300
if hi=1 {
rgb(0)=n : rgb(1)=v : rgb(2)=m
} else {
if hi=3 {
rgb(0)=m : rgb(1)=n : rgb(2)=v
} else {
rgb(0)=v : rgb(1)=m : rgb(2)=n
}
}
} else {
//hiが偶数の場合はK値を使う
k=v-v*s*(60-fn)/15300
if hi=0 {
rgb(0)=v : rgb(1)=k : rgb(2)=m
} else {
if hi=2 {
rgb(0)=m : rgb(1)=v : rgb(2)=k
} else {
rgb(0)=k : rgb(1)=m : rgb(2)=v
}
}
}
x=cnt*3
repeat 3 : poke pal,x+cnt,rgb(cnt) : loop
}
loop
palette ,,,,1
redraw 1
await 16
loop

| |
|