Notcurses
GitHub概要
dankamongmen/notcurses
blingful character graphics/TUI library. definitely not curses.
スター4,009
ウォッチ33
フォーク127
作成日:2019年11月17日
言語:C
ライセンス:Other
トピックス
cclincursesterminalterminal-emulators
スター履歴
データ取得日時: 2025/7/25 11:08
Notcurses
Notcursesは、最新のターミナル機能を最大限に活用する高性能TUIライブラリです。グラフィックス、動画、マルチメディアコンテンツの表示をサポートし、従来のTUIライブラリの限界を超えた表現力を提供します。C言語で書かれたライブラリのRustバインディングとして提供されています。
特徴
高度なグラフィックス機能
- ピクセル操作: 真のピクセルレベルの描画
- 画像表示: JPEG、PNG、GIF、WebPなどの画像フォーマット対応
- 動画再生: ターミナル内での動画再生機能
- 透過処理: アルファチャンネルのサポート
- ブレンディング: 高度な色混合処理
パフォーマンス最適化
- ダブルバッファリング: ちらつきのない描画
- 差分レンダリング: 変更部分のみの再描画
- 並列処理: マルチコアCPUを活用
- メモリ効率: 最適化されたメモリ使用
- ハードウェアアクセラレーション: 可能な場合はGPU活用
豊富な機能セット
- Unicode完全対応: 絵文字、結合文字、RTL言語
- 24ビットカラー: トゥルーカラーサポート
- マウス対応: 高精度マウストラッキング
- サウンド: オーディオ再生機能
- 統計情報: レンダリング統計とデバッグ情報
ターミナル互換性
- 幅広いサポート: 主要なターミナルエミュレータに対応
- 機能検出: ターミナル機能の自動検出
- グレースフルデグレーデーション: 機能が使えない場合の代替処理
- Sixel/Kitty: グラフィックスプロトコル対応
基本的な使用方法
インストール
[dependencies]
notcurses = "3.0"
基本的な初期化と描画
use notcurses::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Notcursesの初期化
let mut nc = Notcurses::new()?;
// 標準プレーンを取得
let mut stdplane = nc.stdplane();
// テキストを描画
stdplane.putstr("Hello, Notcurses!")?;
// 色を設定して描画
stdplane.set_fg_rgb(0xFF0000)?; // 赤
stdplane.set_bg_rgb(0x000000)?; // 黒
stdplane.putstr_yx(2, 0, "Colored text")?;
// レンダリング
nc.render()?;
// キー入力を待つ
nc.get_blocking(None)?;
Ok(())
}
プレーンの操作
use notcurses::*;
fn create_window(nc: &mut Notcurses) -> Result<NcPlane, NcError> {
let opts = NcPlaneOptions {
y: 5,
x: 10,
rows: 10,
cols: 40,
userptr: std::ptr::null_mut(),
name: Some("mywindow".to_string()),
resizecb: None,
flags: 0,
margin_b: 0,
margin_r: 0,
};
// 新しいプレーンを作成
let mut plane = NcPlane::new(nc, &opts)?;
// ボーダーを描画
plane.perimeter_rounded(0, 0, 0)?;
// タイトルを追加
plane.putstr_yx(0, 2, " Window Title ")?;
// コンテンツを追加
plane.putstr_yx(2, 2, "This is a window!")?;
Ok(plane)
}
画像の表示
use notcurses::*;
fn display_image(
nc: &mut Notcurses,
path: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let mut stdplane = nc.stdplane();
// ビジュアルを作成
let mut visual = NcVisual::from_file(path)?;
// スケーリングオプション
let vopts = NcVisualOptions {
n: Some(&mut stdplane),
scaling: NcScale::Scale,
y: 0,
x: 0,
begy: 0,
begx: 0,
leny: 0,
lenx: 0,
blitter: NcBlitter::Default,
flags: 0,
transcolor: 0,
pxoffy: 0,
pxoffx: 0,
};
// 画像をレンダリング
visual.blit(nc, &vopts)?;
nc.render()?;
Ok(())
}
アニメーション
use notcurses::*;
use std::time::Duration;
use std::thread;
fn animate_text(nc: &mut Notcurses) -> Result<(), NcError> {
let mut plane = nc.stdplane();
let text = "Animated Text";
let max_x = plane.dim_x() as i32 - text.len() as i32;
for x in 0..max_x {
plane.erase();
// 虹色のグラデーション
let hue = (x as f32 / max_x as f32) * 360.0;
let (r, g, b) = hsl_to_rgb(hue, 1.0, 0.5);
plane.set_fg_rgb8(r, g, b)?;
plane.putstr_yx(5, x, text)?;
nc.render()?;
thread::sleep(Duration::from_millis(50));
}
Ok(())
}
fn hsl_to_rgb(h: f32, s: f32, l: f32) -> (u8, u8, u8) {
let c = (1.0 - (2.0 * l - 1.0).abs()) * s;
let x = c * (1.0 - ((h / 60.0) % 2.0 - 1.0).abs());
let m = l - c / 2.0;
let (r, g, b) = match (h / 60.0) as u8 {
0 => (c, x, 0.0),
1 => (x, c, 0.0),
2 => (0.0, c, x),
3 => (0.0, x, c),
4 => (x, 0.0, c),
_ => (c, 0.0, x),
};
(
((r + m) * 255.0) as u8,
((g + m) * 255.0) as u8,
((b + m) * 255.0) as u8,
)
}
高度な機能
メニューシステム
use notcurses::*;
fn create_menu(nc: &mut Notcurses) -> Result<NcMenu, NcError> {
let sections = vec![
NcMenuSection {
name: "File".to_string(),
items: vec![
NcMenuItem {
desc: "New".to_string(),
shortcut: Some("Ctrl+N".to_string()),
},
NcMenuItem {
desc: "Open".to_string(),
shortcut: Some("Ctrl+O".to_string()),
},
NcMenuItem {
desc: "Save".to_string(),
shortcut: Some("Ctrl+S".to_string()),
},
],
},
NcMenuSection {
name: "Edit".to_string(),
items: vec![
NcMenuItem {
desc: "Copy".to_string(),
shortcut: Some("Ctrl+C".to_string()),
},
NcMenuItem {
desc: "Paste".to_string(),
shortcut: Some("Ctrl+V".to_string()),
},
],
},
];
let opts = NcMenuOptions {
sections,
..Default::default()
};
NcMenu::new(&mut nc.stdplane(), &opts)
}
グラフとチャート
use notcurses::*;
fn draw_chart(
plane: &mut NcPlane,
data: &[f64],
) -> Result<(), NcError> {
let height = plane.dim_y() as usize;
let width = plane.dim_x() as usize;
// データを正規化
let max_val = data.iter().cloned().fold(f64::MIN, f64::max);
let min_val = data.iter().cloned().fold(f64::MAX, f64::min);
let range = max_val - min_val;
// グラフを描画
for (i, &value) in data.iter().enumerate() {
let x = (i * width) / data.len();
let normalized = (value - min_val) / range;
let y = height - (normalized * height as f64) as usize - 1;
// バーを描画
for bar_y in y..height {
plane.putchar_yx(bar_y as i32, x as i32, '█')?;
}
}
Ok(())
}
エコシステム
関連プロジェクト
- notcurses-rs: 公式Rustバインディング
- ncplayer: メディアプレーヤー
- ncneofetch: システム情報表示ツール
- nctetris: テトリスゲーム実装
ツールとユーティリティ
- notcurses-demo: 機能デモンストレーション
- ncls: lsコマンドの拡張版
- ncplayer: ターミナルメディアプレーヤー
利点
- 最先端機能: 最新のターミナル機能を完全活用
- 高パフォーマンス: 最適化されたレンダリングエンジン
- 豊富な表現力: 画像、動画、グラフィックスのサポート
- プロフェッショナル: 商用品質のライブラリ
- 活発な開発: 継続的な機能追加と改善
制約事項
- 複雑性: 高機能ゆえに学習曲線が急
- 依存関係: C言語ライブラリへの依存
- ターミナル要件: 最新機能には対応ターミナルが必要
- リソース使用: メモリとCPU使用量が多い
- 移植性: 一部機能はプラットフォーム固有
他のライブラリとの比較
項目 | Notcurses | Ratatui | Cursive |
---|---|---|---|
グラフィックス | 完全対応 | テキストのみ | テキストのみ |
パフォーマンス | 非常に高い | 高い | 高い |
学習コスト | 非常に高い | 中 | 低〜中 |
機能の豊富さ | 最高 | 中 | 中 |
移植性 | 中 | 高 | 高 |
まとめ
Notcursesは、ターミナルアプリケーションの可能性を最大限に引き出す革新的なライブラリです。従来のTUIライブラリでは不可能だった、画像表示、動画再生、高度なグラフィックス表現を可能にします。学習曲線は急ですが、プロフェッショナルなターミナルアプリケーションや、視覚的に印象的なTUIを作成したい開発者にとって最適な選択肢です。