2007 年 1 月 14 日 23 時 55 分

画面バッファの作成


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


RFB の画素形式は、初期化時にサーバが既定値を決め、
主処理においてはクライアントが自由に変更できる。
それぞれ ServerInit と SetPixelFormat メッセージだ。

サーバ側では常に自然な画素形式を使い、
通信時に画像形式を変換すると言う手もあるが、
それには多くのオーバヘッドが掛かると思われる。

そこで、クライアントの指定した画素形式に応じて、
サーバは常に最適な画面バッファを持つことにする。
また、今回は実装の手間を考え TrueColor だけに対応しよう。
Java で動的にカラーテーブルを扱うには手間がかかる上に、
VNC クライアントの大半がカラーテーブルを扱わないからだ。

まずは、PIXEL_FORMAT 構造(PixelFormat クラス)を、
ColorModel に変換する必要がある。

getRedMax() は、赤の取り得る最大値を表し、
getRedShift() は、ピクセルの赤を示すビット位置を表す。
そのため、getRedMax() で得られた最大値を、
getRedShift() だけ 左シフトすれば、
赤要素のビットマスクが計算できることになる。

   // PixelFormat format = ...;

    if (!format.isTrueColor())
            throw new IOException("Can't handle indexed pixel format.");

   int redMask = format.getRedMax() << format.getRedShift();
   int greenMask = format.getGreenMax() << format.getGreenShift();
   int blueMask = format.getBlueMax() << format.getBlueShift();

次に、ピクセルが占めるサイズだが、PixelFormat には、
getBitPerPixel() と getDepth() の 2 つの値がある。
RFB のピクセルサイズと Java の転送型のサイズを一致させるためには、
getBitPerPixel() で得られる 8, 16, 32 を使う必要がある。

    ColorModel model = new DirectColorModel(
            format.getBitPerPixel(), redMask, greenMask, blueMask);

ColorModel ができたら、それを元にして WritableRaster を生成する事ができる。

    WritableRaster raster = model.createCompatibleWritableRaster(
            width, height);


次に描画のことを考えなければならない。

WritableRaster は書き込み可能な画面データを提供してくれるが、
その扱いは少し面倒で、単一の点もしくは矩形領域に、
ピクセル値(RGB パック済み)を読み書きする必要がある。

Java では、java.awt.Graphics クラスを基本とする、
描画に関する強力なクラス群がそろっている。
Graphics のメソッドを使って描画できるようにすれば、
サーバの画面を描画するのには非常に便利となるのだ。

この橋渡しをしてくれるのが、java.awt.image.BufferedImage だ。

BufferedImage クラスは、WritableRaster に対して、
画像として操作可能な能力を付与する機能を持つ。
BufferedImage は java.awt.Image を実装しているので、
Image の一種として色々な場所で利用可能だ。

また、BufferedImage の createGraphics() メソッドを使うと、
WritableRaster に描画するための Graphics を作成可能である。
この Graphics を使って描画操作を行うことで、
WritableRaster に高度な描画ロジックを適用する事が可能となる。

    BufferedImage canvas = new BufferedImage(model, raster, false, null);

……ううむ。グラフィックス関係はえらいややこしいな。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.