供參考,我在想,長曝光是不是可以用固定攝影來轉成長曝光效果,有待驗證, 但是這個想法可以用底下的命令來實現, 系統中要安裝 ffmpeg, imagemagick # 底下存成 video2image.sh, 其中 RATE 是指要從影片一秒抓幾張圖(不是影片本身的 fps) # Usage: video2image.sh MP4_FILE RATE MP4=$1; shift [ -z $MP4 ] && echo "Usage: %0 MP4_FILE RATE" && exit 1 RATE=$1; shift [ -z $RATE ] && RATE=1 mkdir out echo "ffmpeg -i ${MP4} -r ${RATE} out/%04d.jpg" ffmpeg -i ${MP4} -r ${RATE} out/%04d.jpg ls out/* cp out/0001.jpg oo.jpg N=$(\ls out/*jpg | wc -l) echo "N=$N" for i in $(seq 2 1 ${N} ); do F=$(printf "%04d" $i) echo "convert out/${F}.jpg oo.jpg -compose overlay -composite oo.jpg" convert out/${F}.jpg oo.jpg -compose overlay -composite oo.jpg done rm -rf out
2024/02/22
2021/11/28
DualBoot with freedos
懶得說太多,有問題的朋友請回覆
先說 grub.cfg 怎麼下:
menuentry "FreeDOS testing" {
insmod part_msdos
freedos (hd0,msdos1)/KERNEL.sys
}
沒錯,上面跟在 google 找到的都不太一樣,自行揣摩一下囉,這個是真的能動的我用的是 freedos 1.3 rc4(版本不重要) 的 LiveCD 解壓縮 zip 檔之後是 iso 檔, 將之整個 cp 到 (hd0,msdos1)/ 也就是 DOS/ 清單如下:
-r-xr-xr-x 1 root root 4016 11月 28 11:18 fdauto.bat* drwxr-xr-x 12 root root 4096 11月 28 11:13 freedos/ drwxr-xr-x 4 root root 4096 4月 30 2021 FDOS-x86/ drwxr-xr-x 2 root root 4096 4月 30 2021 isolinux/ drwxr-xr-x 15 root root 4096 4月 30 2021 packages/ drwxr-xr-x 3 root root 4096 4月 30 2021 devel/ drwxr-xr-x 3 root root 4096 4月 30 2021 games/ drwxr-xr-x 3 root root 4096 4月 30 2021 util/ -r-xr-xr-x 1 root root 182 4月 30 2021 fdconfig.sys* -r-xr-xr-x 1 root root 85048 4月 30 2021 COMMAND.COM* -r-xr-xr-x 1 root root 46685 4月 30 2021 KERNEL.SYS* -r-xr-xr-x 1 root root 6744 4月 30 2021 setup.bat*有沒有注意到上面要修改 fdauto.bat?
貼上整個內容
.....到 :FinishCDMode 之前都不變..... :FinishCDMode mkdir \TEMP set TEMP=\TEMP set TMP=%TEMP% SET DOSDIR=\FREEDOS SET BIN=%DOSDIR%\BIN set DOSDRV=C:\ set BIN=C:\FREEDOS\BIN set PATH=\;%BIN%;\UTIL\P7ZIP\ SET NLSPATH=%DOSDIR%\NLS C: CD \ .....到下面兩行前面有變而已..... CALL %DOSDIR%\BIN\FDLIVE.BAT RAMSKIP if "%FDRAMDRV%" == "" goto WarnReadOnly .....以下同....
2021/03/16
[git] add remote origin with ssh
我先講一下我的實驗:
我有個 repository 它的源是國外的,這個我們不管,位置在git clone wade@192.168.20.110:/home/
git commit -a -m 'test for ssh push' && git push
remote: error: By default, updating the current branch in a non-bare repository
remote: is denied, because it will make the index and work tree inconsistent
remote: with what you pushed, and will require 'git reset --hard' to match
remote: the work tree to HEAD.
remote:
remote: You can set the 'receive.denyCurrentBranch' configuration variable
remote: to 'ignore' or 'warn' in the remote repository to allow pushing into
remote: its current branch; however, this is not recommended unless you
remote: arranged to update its work tree to match what you pushed in some
remote: other way.
remote:
remote: To squelch this message and still keep the default behaviour, set
remote: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
[receive]
denyCurrentBranch = ignore
2021/03/15
Mysql JOIN
工作上需要,我有兩個表格,其中一個叫 logger, 一個叫 terminals
logger 很單純,會記錄各種 log, 其中一個欄位會記錄來自哪個 terminal mac, 如果它是 terminal 造成的錯誤。
問題在於,terminals 表格是直式的,就是它的欄位像 attribute, value 這樣的型式,譬如
id attribute value
1 mac 123456789012
1 name t1
2 mac 234567890123
2 name t2
如果想在列出 logger 時,對這類 log 印出這條 log 來自哪個 terminal 該怎麼辦?
對mariadb 而言,因為要的是 logger, 所以要用 LEFT JOIN
LEFT JOIN 的意思是,我要表格左邊的結果,但是在某些條件下合併表格資料
所以就像 SELECT l.id,l.date,l.info,IF(l.mac<>'',t2.name,'') as termname FROM logger AS l
LEFT JOIN Terminals AS t1 on
t1.attribute='mac' AND l.mac<>'' AND l.mac=t1.value
LEFT JOIN Terminals AS t2 on
t1.id=t2.id AND t2.attribute='name'
翻譯成中文大概就像:
我要全部的 logger 資料,其中
如果 mac 欄位有值,那就從 Terminals 表格查,其 attribute='mac' 其值為 mac
但是傳回 Terminals 中相同 id 的 terminal 名稱
有點複雜,我也是想很久才清楚,可以這麼說,LEFT JOIN 是以左邊的(LEFT) 語法為結果,加上條件來自(JOIN) 後面的限制
2021/02/23
[dd] 利用 dd split & merge
對超大檔案的分割與合併,我一般是使用 split 與 cat
結果經過實驗發現,使用 dd 的效率會非常高,
請參考 https://www.linuxquestions.org/linux/answers/applications_gui_multimedia/splitting_and_merging_files_using_dd
底下以 shell 搭配來操作的話,類似 :
D=0; for i in `seq 1 1 52`; do dd if=W-2016_TM-11.2-disk1.vmdk.`printf "%03d" $i` of=W-2016_TM-11.2-disk1.vmdk bs=1M count=200 seek=$D; D=$(( D+200 )); done
0)最前面的 D=0 每次重設變數,要養成好習慣
1) seq 用來自動產生序列數字
2)printf 用來將檔名的數字固定成補0的3個數位
3)dd 用 seek 來將下一個檔案附加到前一個的後面
4)最後利用 現代 shell 的 $(( ... )) 來做運算
2020/10/27
avconv had been gone 不見了
我想將影片放慢,先前都用 avconv, 結果現在卻找不到套件,
只好又用回 ffmpeg, 語法如下:
ffmpeg -y -i 4x4.mp4 -vf "setpts=16*PTS" -r 24.5 slow.mp4
影片原來 fps 並不是 24.5, 而是 30, 不過不重要
重點是我放慢 16 的方式如上面的 16 , 這樣做,影片會被拉長
至於後面的 24.5 則是輸出的 fps, 可以不指定或是其他值
2020/07/15
[shell] script for 網路小說
利用 elinks(需要自行安裝, apt-get install elinks) 來讀小說,相當方便,同時也可以翻譯成繁中
平常我是這樣用
nob URL
如果離開後想續讀,可以直接打 nob
至於下一頁,通常我是按兩次 q, 一次是離開 elinks, 一次是翻下一頁
如果要前一頁,則先 q, 再按 p
請自行翻閱 shell scripts
URL=$1
[ "x$URL" = "x" ] && URL=$(cat $HOME/no.url)
read_current() {
if [ -e '/tmp/no.txt' ]; then
HEAD=$(cat /tmp/no.txt | grep "章節列表")
P=$(echo "$HEAD" | cut -d "[" -f2 | cut -d "]" -f1)
H=$(echo "$HEAD" | cut -d "[" -f3 | cut -d "]" -f1)
N=$(echo "$HEAD" | cut -d "[" -f4 | cut -d "]" -f1)
URL=$(grep "${N}. https" /tmp/no.txt | sed -e 's/.*https/https/')
# less /tmp/no.txt
else
echo "Usage: $0 {URL}"
exit 1
fi
}
[ "x$URL" = "x" ] && read_current
while [[ $URL == "https:"* ]]; do
echo "$URL" > /tmp/no.txt
echo "$URL" > $HOME/no.url
elinks -dump "$URL" | cconv -f UTF8-CN -t UTF8-TW - >> /tmp/no.txt
less /tmp/no.txt
read_current
PREV=$(grep "${P}. https" /tmp/no.txt | sed -e 's/.*https/https/')
BM=$(grep "${H}. https" /tmp/no.txt | sed -e 's/.*https/https/')
NEXT=$(grep "${N}. https" /tmp/no.txt | sed -e 's/.*https/https/')
echo "Press ESC key to quit, others to continue..."
Q=0
# read a single character
while read -r -n1 key; do
[[ $key == $'\e' ]] && Q=1 && break
# echo -e -n "KEY='${key}'\nPREV=$PREV\nBM=$BM\nNEXT=$NEXT\n"
if [ "x${key}" = "xp" -o "x${key}" = "xP" ]; then
URL="${PREV}"
elif [ "${key}" = "q" -o "${key}" = "Q" -o "${key}" = "n" -o "${key}" = "N" -o "${key}" = "" ]; then
URL="${NEXT}"
else
URL="${BM}"
fi
break
done
[ $Q = "1" ] && break
done
2020/07/09
shutdown linux 關機
嵌入式系統有不同的實作方式,包括 完整的 Linux Distribution 都有不同的方式開機。
在桌面(X)當掉的時候,或許還可以從遠端連線(沒錯), 或許還可以按 SysRq 鍵,
這樣就有辦法讓系統安全的關機或重新開機。
我遇到一個系統,用 busybox 建構的,無法關機,底下做法成功的機會大增:
echo 510 > /proc/sys/kernel/sysrq
echo o > /proc/sysrq-trigger
詳閱該文的說明
2018/12/15
a020: 身分證檢驗
#include
/*
A=10 台北市 J=18 新竹縣 S=26 高雄縣
B=11 台中市 K=19 苗栗縣 T=27 屏東縣
C=12 基隆市 L=20 台中縣 U=28 花蓮縣
D=13 台南市 M=21 南投縣 V=29 台東縣
E=14 高雄市 N=22 彰化縣 W=32 金門縣
F=15 台北縣 O=35 新竹市 X=30 澎湖縣
G=16 宜蘭縣 P=23 雲林縣 Y=31 陽明山
H=17 桃園縣 Q=24 嘉義縣 Z=33 連江縣
I=34 嘉義市 R=25 台南縣
*/
int map[] = { // 英文字轉成上述數字後,個位數*9+十位數
1, // A
10,// B
19,// C
28,// D
37,// E
46,// F
55,// G
64,// H
39,// I
73,// J
82,// K
2, // L
11,// M
20,// N
48,// O
29,// P
38,// Q
47,// R
56,// S
65,// T
74,// U
83,// V
21,// W
3, // X
12,// Y
30,// Z
};
int isValid(char* d) {
int cs = map[d[0]-'A'];
for (int i=1; i<9 i="" p=""> cs += (d[i] - '0') * (9-i);
}
cs += (d[9] - '0');
return cs%10 == 0;
}
int main ()
{
char id[20];
while (scanf("%s", id) == 1) {
printf ("%s\n", isValid(id)?"real":"fake");
}
return 0;
}
9>
a017: 五則運算
// 底下這一行,是因為要用 getline(), 這個是 c++ 才有的,或是要告訴 gcc 說,這個是 gnu 額外提供給 c 的
#define _GNU_SOURCE
#include
char *buf;
char *express;
// peek() 不移動字元位置,只傳回指標目前所指的字元
char peek() {
while (*express == ' ') ++express; // 一律略過空白字元
return *express;
}
// 因為 peek() 會略過空白字元,這邊直接傳回指標所指的字元
char get() { return *(express++); }
// 把數字傳回去,因為數字是連續的,所以....
int number() {
int result = get() - '0';
while (peek() >= '0' && peek() <= '9') result = 10*result + (get() - '0');
return result;
}
// factor() 可以看成『分解成 + - 的『項』,小括號內的話,視為一項
int expression(); // 要遞迴呼叫,所以得先定義方法
int factor() {
if (peek() >= '0' && peek() <= '9') return number();
else if (peek() == '(') { // 遇上括號,則再遞回呼叫 expression()
get(); // '('
int result = expression();
get(); // ')'
return result;
}
else if (peek() == '-') {
get();
return -factor();
}
return 0; // error
}
// term() 則將各項運算結合起來, 主要是以 * / % 為主
int term() {
int result = factor();
char p = peek();
while (p == '*' || p == '/' || p == '%') {
p = get();
if (p == '*') result *= factor();
else if (p == '/') result /= factor();
else result %= factor();
p = peek();
}
return result;
}
int expression() {
int result = term(); // 先取得第一項
while (peek() == '+' || peek() == '-') { // 如果遇到 + - 號的話,則運算下一項的結合
if (get() == '+') result += term();
else result -= term();
}
return result;
}
int main ()
{
size_t n;
while (getline(&buf, &n, stdin) >= 0) {
express = buf;
int result = expression();
printf ("%d\n", result);
}
return 0;
}
a016: 數獨(SUDOKU)
#include
int check(int* a) {
// 1) 比對直線(橫+直)
for (int k=0; k<9 k="" p=""> for (int i=0; i<9 i="" p=""> for (int j=i+1; j<9 j="" p=""> if (*(a+k*9+i) == *(a+k*9+j)) return 0; // 橫線
if (*(a+i*9+k) == *(a+j*9+k)) return 0; // 直線
}
}
}
// 3) 比對3x3
for (int m=0; m<3 m="" p=""> for (int n=0; n<3 n="" p=""> // 比對每個 3x3
for (int j=0; j<9 j="" p=""> for (int i=0; i<9 i="" p=""> if (i != j && *(a+(m*3+j/3)*9+j%3+n*3) == *(a+(m*3+i/3)*9+i%3+n*3)) return 0;
}
}
}
}
return 1;
}
int main ()
{
int a[81];
int *pa;
while (!feof(stdin)) {
pa = a;
for (int i=0; i<9 i="" p=""> if (scanf ("%d %d %d %d %d %d %d %d %d", pa+0, pa+1, pa+2, pa+3, pa+4, pa+5, pa+6, pa+7, pa+8) != 9) return 0;
pa += 9;
}
printf ("%s\n", check(a)?"yes":"no");
}
return 0;
}
9>9>9>3>3>9>9>9>
a015: 矩陣的翻轉
#include
int main ()
{
int m, n;
int a[100][100];
while (scanf ("%d %d", &m, &n) == 2) {
for (int j=0; j
for (int j=0; j
printf ("%d\n", a[m-1][j]);
}
}
return 0;
}
a013: 羅馬數字
#include
#include
#include
#include
// 阿拉伯數字 --> 羅馬數字
int a2r(unsigned int val, char* res, size_t sz) {
char *twas[] = {"", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"};
char *wans[] = {"", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"};
char *thos[] = {"", "M", "MM", "MMM", "Mv", "v", "vM", "vMM", "vMMM", "Mx"};
char *huns[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
char *tens[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
char *ones[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
int size[] = { 0, 1, 2, 3, 2, 1, 2, 3, 4, 2};
if (val < 0) { strcpy(res, "UNKNOWN"); return 1; }
if (val == 0) { strcpy(res, "ZERO"); return 1; }
while (val >= 1000000) {
if (sz-- < 1) return 0;
*res++ = 'm';
val -= 1000000;
}
// Add each of the correct elements, adjusting as we go.
if (sz < size[val/100000]) return 0;
sz -= size[val/100000];
strcpy (res, twas[val/100000]); res += size[val/100000]; val = val % 100000;
if (sz < size[val/10000]) return 0;
sz -= size[val/10000];
strcpy (res, wans[val/10000]); res += size[val/10000]; val = val % 10000;
if (sz < size[val/1000]) return 0;
sz -= size[val/1000];
strcpy (res, thos[val/1000]); res += size[val/1000]; val = val % 1000;
if (sz < size[val/100]) return 0;
sz -= size[val/100];
strcpy (res, huns[val/100]); res += size[val/100]; val = val % 100;
if (sz < size[val/10]) return 0;
sz -= size[val/10];
strcpy (res, tens[val/10]); res += size[val/10]; val = val % 10;
if (sz < size[val]) return 0;
sz -= size[val];
strcpy (res, ones[val]); res += size[val];
// Finish string off.
if (sz < 1) return 0;
*res = '\0';
return 1;
}
int r2a_in_char(char r) {
switch (r) {
case 'I': return 1;
case 'V': return 5;
case 'X': return 10;
case 'L': return 50;
case 'C': return 100;
case 'D': return 500;
case 'M': return 1000;
case 'v': return 5000;
case 'x': return 10000;
case 'l': return 50000;
case 'c': return 100000;
case 'd': return 500000;
case 'm': return 1000000;
default: return 0;
}
}
int r2a(char *str) {
int res = 0;
int max = strlen(str);
for (int i=0; i
int s1 = r2a_in_char(str[i]);
if (i+1 < max) {
// 往後看,將下一個字元從羅馬數字轉成阿拉伯數字
int s2 = r2a_in_char(str[i+1]);
// 比對前後文....
if (s1 >= s2) { // 前面大於等於後面,表示加法,直接加起來
res = res + s1;
} else { // 前面小於後面,表示減法: 加後面減前面
res = res + s2 - s1;
i++; // i++ 之後,跳過下一符號
}
} else { // 結束.....
res = res + s1;
i++;
}
}
return res;
}
int main ()
{
int n, a, b;
char r1[100], r2[100];
char res[100];
while (scanf ("%s %s", r1, r2) == 2) {
a = r2a(r1);
b = r2a(r2);
a2r(a>b?a-b:b-a, res, 100);
printf ("%s\n", res);
}
return 0;
}
a010: 因數分解
#include
#include
int main ()
{
int n, nn;
while (scanf ("%d", &n) == 1) {
int last = -1;
int cnt=1;
nn = sqrt(n);
// 因為所有質因數只有2是偶數,先處理2
while (!(n % 2)) {
n >>= 1;
if (last != 2) {
printf ("2");
last = 2;
cnt = 1;
} else cnt++;
}
if (cnt > 1) {
printf ("^%d", cnt);
cnt = 1;
}
for (int i = 3; i <= nn;) {
if (n % i == 0) {
n /= i;
if (last != i) {
if (cnt > 1) printf ("^%d * %d", cnt, i);
else {
if (last <= 0) printf ("%d", i);
else printf (" * %d", i);
}
cnt = 1;
} else cnt++;
last = i;
} else i += 2;
}
if (cnt > 1) {
if (n > 1)
printf ("^%d * %d\n", cnt, n);
else
printf ("^%d\n", cnt);
} else if (n > 1) {
if (last <= 0)
printf ("%d\n", n);
else
printf (" * %d\n", n);
} else puts("");
}
return 0;
}
上面的速度應該是比較快的,底下還有一個比較簡明的版本
#include
#include
a009: 解碼器
#include
int main (int argc, char* argv[])
{
int c;
while (EOF != (c = getchar())) {
if (c == '\n') printf ("\n");
else printf ("%c", (char)((c + 'C' - 'J')%255));
}
return 0;
}
a006: 一元二次方程式
#include
#include
int main (int argc, char* argv[])
{
int a, b, c;
while (scanf ("%d %d %d", &a, &b, &c) == 3) {
double r = (double)((b*b) - 4*(a*c));
if (r == 0.0) {
printf ("Two same roots x=%.0lf\n", (double)(-b/(2.0*a)));
} else if (r > 0.0) {
double s = sqrt(r);
printf ("Two different roots x1=%.0lf , x2=%.0lf\n", (double)((-b+s)/(2.0*a)), (double)((-b-s)/(2.0*a)));
} else {
printf ("No real root\n");
}
}
return 0;
}
a005: Eva 的回家作業
#include
int main (int argc, char* argv[])
{
int n, a[4], r;
scanf ("%d", &n);
for (int i=0; i
if ((a[3] - a[0]) == (3*(a[1] - a[0]))) r = a[3]+a[3]-a[2];
else r = a[3]*a[3]/a[2];
printf ("%d %d %d %d %d\n", a[0], a[1], a[2], a[3], r);
}
return 0;
}
a004: 文文的求婚
#include
int main (int argc, char* argv[])
{
int a;
char m[2][10] = { "平", "閏" };
while (scanf ("%d", &a) == 1) {
printf ("%s年\n", m[!(a%400) || ((a%100) && !(a%4))]);
}
return 0;
}
a003: 兩光法師占卜術
#include
int main (int argc, char* argv[])
{
int a, b;
char m[3][10] = { "普通", "吉", "大吉" };
while (scanf ("%d %d", &a, &b) == 2) {
printf ("%s\n", m[(a*2+b)%3]);
}
return 0;
}
zj-a002 簡易加法
#include
int main (int argc, char* argv[])
{
int a, b;
while (scanf ("%d %d", &a, &b) == 2) {
printf ("%d\n", a+b);
}
return 0;
}