日記帳

日記です。

Mac OS X でスクリーンキャプチャー

QuickDraw 編.

  • GetQDGlobalsScreenBits() でスクリーンの内容持つ Bitmap で取得
  • NewGWorld() で 32bit RGB の GWorld を作成
  • SetGWorld() で作った GWorld を描画対象として選択
  • CopyBits() で Bitmap から GWorld へコピー
  • GetGWorldPixMap() で GWorld の Pixmap を取得
  • GetPixBaseAddr(pixmap) でピクセルデータのアドレスを取得して好きにいじる

P3 フォーマットで出力するサンプル.

/************************************************************
* gcc -framework ApplicationServices capture_screen_qd-02.c
************************************************************/
#include <stdio.h>
#include <stdint.h>

#include <ApplicationServices/ApplicationServices.h>

#define PPM_FILE_NAME "capture_screen_qd.ppm"

int
main(int argc, char *argv[])
{
	BitMap bitmap;
	Rect bounds;
	GWorldPtr gworld;
	OSErr result;
	int w, h;

	/* Get Screen Bits */
	GetQDGlobalsScreenBits(&bitmap);
	bounds = bitmap.bounds;
	w = bounds.right - bounds.left;
	h = bounds.bottom - bounds.top;

	/* Create 32 bpp GWorld */
	result = NewGWorld(&gworld, 32, &bounds, NULL, NULL, 0);
	if (result == noErr)
	{
		GWorldPtr backupGWorld;
		GDHandle backupGDH;
		FILE *file;

		/* backup GWorld */
		GetGWorld(&backupGWorld, &backupGDH);
		SetGWorld(gworld, NULL);

		/* Copy Screen Bits */
		LockPortBits(gworld);
		CopyBits(
			&bitmap, GetPortBitMapForCopyBits(gworld), 
			&bounds, &bounds, 
			srcCopy, NULL);
		UnlockPortBits(gworld);

		/* Write PPM file */
		file = fopen(PPM_FILE_NAME, "wb");
		if (file != NULL)
		{
			PixMapHandle pixmap;
			uint8_t *baseAddr;
			long rowBytes;
			int x, y;

			pixmap = GetGWorldPixMap(gworld);
			baseAddr = (uint8_t *)GetPixBaseAddr(pixmap);
			rowBytes = GetPixRowBytes(pixmap);
			
			fprintf(file, "P3\n");
			fprintf(file, "%d %d\n", w, h);
			fprintf(file, "255\n");

			LockPixels(pixmap);
			for (y = 0;y < h;y++)
			{
				for (x = 0;x < w;x++)
				{
					int index = y * rowBytes + x * 4;
					uint32_t pixel = *((uint32_t *)&(baseAddr[index]));
					fprintf(file, "%d %d %d ",
						(pixel & 0x00ff0000) >> 16,
						(pixel & 0x0000ff00) >> 8,
						(pixel & 0x000000ff));
				}
				fprintf(file, "\n");
			}
			UnlockPixels(pixmap);
		}

		SetGWorld(backupGWorld, backupGDH);
		DisposeGWorld(gworld);
	}

	return 0;
}

X11 版はどうした? いや面倒なことをやるしかないってのは解っているんだ.でもやりたくないんだ.だって面倒だし…