Wacom Stylus SDKを利用したサインアプリの実装②
2013年10月16日
前回のソースコードに追記する形で、筆圧の情報を反映させた線を描画する方法を紹介します。
ペンの位置情報は、タッチイベントとして発生するので、特に意識せず取得することが可能です。
1. デバイスのペアリング
デバイスを認識しただけでは、筆圧を取得することはできません。
認識したデバイスをペアリングする必要があります。
また、筆圧の最大値の情報がWacomDeviceに定義されていますので、変数に保持しておきます。
- (void) deviceDiscovered:(WacomDevice *)device { // 認識したデバイスをペアリングする [[WacomManager getManager] selectDevice:device]; // 筆圧の最大値を取得する maximumPressure = [device getMaximumPressure]; }
2. WacomStylusEventCallbackの採用
筆圧はWacomDiscoveryCallbackではなく、WacomStylusEventCallbackを採用し、取得する必要があります。
また、筆圧の情報を保持するための変数を定義しておきます。
@interface WDViewController : UIViewController<WacomDiscoveryCallback, WacomStylusEventCallback> { // 筆圧の最大値 NSInteger maximumPressure; // 現在の筆圧 CGFloat currentPressure; } @end
3. 筆圧取得の処理追加
筆圧の取得は、stylusEventを利用することで、取得することができます。
筆圧はタッチイベントとは別のイベントですので、先ほど定義した変数に保持します。
// スタイラスイベント - (void) stylusEvent:(WacomStylusEvent *)stylusEvent { if ([stylusEvent getType] == eStylusEventType_PressureChange) { // 筆圧の変更イベント currentPressure = [stylusEvent getPressure]; NSLog(@"Pressure : %f", currentPressure); } }
ここで一度アプリケーションを実行させます。
ペンをiPadに押し付けると、どのような値が筆圧として、取得しているかが分かりますが、1からではなく、0から始まりますので注意してください。
また、Intuos Creative Stylusの場合、最大2047までの値が取得できますが、今後別のスタイラスペンが発売された時のために、ペアリング時などに筆圧の最大値を取得するように実装しています。
4. タッチイベントの追加
実際にタッチを行った時に、線を描画する処理を追加します。
今回はUIBezierPathを利用して線を描画します。
// タッチ開始 - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint currentPoint = [[touches anyObject] locationInView:self.view]; // パスの作成 self.bezierPath = [UIBezierPath bezierPath]; self.bezierPath.lineCapStyle = kCGLineCapRound; [self.bezierPath moveToPoint:currentPoint]; // 現在位置 lastPoint = currentPoint; } // 移動イベント - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint currentPoint = [[touches anyObject] locationInView:self.view]; // 現在の筆圧で線の太さを決定する self.bezierPath.lineWidth = [self getLineWidth]; // 線の描画 [self.bezierPath addQuadCurveToPoint:currentPoint controlPoint:lastPoint]; [self drawLine:self.bezierPath]; // 描画した画像の保持 self.lastImage = self.drawView.image; // パスの作成 self.bezierPath = [UIBezierPath bezierPath]; self.bezierPath.lineCapStyle = kCGLineCapRound; [self.bezierPath moveToPoint:currentPoint]; // 最後に描画した位置の保存 lastPoint = currentPoint; } // タッチ終了 - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint currentPoint = [[touches anyObject] locationInView:self.view]; [self drawEnd:currentPoint]; } // タッチのキャンセル - (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint currentPoint = [[touches anyObject] locationInView:self.view]; [self drawEnd:currentPoint]; }
[self getLineWidth]では、現在の筆圧から線の太さを決定しています。
初期は筆圧が0のため、太さが0にならないようにしています。
// ペンの太さ取得 - (CGFloat) getLineWidth { if (maximumPressure == 0) { // 筆圧の最大値未取得 return 1.0f; } // 現在の筆圧からペンの太さを決定する CGFloat w = MAX_LINE_WIDTH * currentPressure / maximumPressure; if (w < 1.0f) { w = 1.0f; } return w; }
タッチイベントの終了とキャンセルでは同じ処理のため、drawEndというメソッドを作成し、処理を共通化しています。
// 描画の終了 - (void) drawEnd:(CGPoint)currentPoint { // 現在の筆圧で線の太さを決定する self.bezierPath.lineWidth = [self getLineWidth]; // 線の描画 [self.bezierPath addQuadCurveToPoint:currentPoint controlPoint:lastPoint]; [self drawLine:self.bezierPath]; // 描画した画像の保持 self.lastImage = self.drawView.image; }
線の描画を行っているdrawLineは以下のような処理となっています。
画像に線を描画し、UIImageViewに設定しています。
// 線の描画処理 - (void)drawLine:(UIBezierPath*)path { UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0.0); [self.lastImage drawAtPoint:CGPointZero]; [[UIColor blackColor] setStroke]; [path stroke]; self.drawView.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); }
以上で線を描画するアプリケーションが完成しましたので、
実際にアプリケーションを実行し、ペンで線を引いてみます。
以上で、筆圧を取得し線を描画する処理ができました。
次回はサイドスイッチのイベント取得と、パームリジェクションの有効化・無効化の実装方法を紹介します。
今回実装したソースコードはこちらからダウンロードできます。
実際に、ダウンロードして試していただければと思います。
ソースコードには、Wacom Stylus SDKは付属しておりませんので、以下のページからWacom Stylus SDKを入手し、WacomDevice.frameworkを追加してください。