«

»

2月 11

Air Native Extension(ANE) 実行速度実験2 + 画像処理

このエントリーを含むはてなブックマークはてなブックマーク - Air Native Extension(ANE) 実行速度実験2 + 画像処理 Googleブックマークに追加 このエントリをつぶやくこのWebページのtweets

前回に引き続き実行速度比較をしてみます。
今回は簡単な画像処理です。
環境は前回と同じくWindows7

グレースケール化の処理をActionScript3.0, ANEを利用してC++で実行させた場合の速度比較の表

今回は大体ネイティブの方が10倍速いという結果になりました。

今回のソース
実行したAS

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.filters.ConvolutionFilter;
	import flash.geom.Point;
	import flash.utils.getTimer;
	
	import jp.ane.sample.ANE_CV;
	
	public class ANE_ComputerVisionTest extends Sprite
	{
		[Embed(source="Koala5.jpg")]
		private var Img:Class;
		private var bmpData:BitmapData;
		private var bmp:Bitmap;
		
		private var CV:ANE_CV = new ANE_CV();
		
		public function ANE_ComputerVisionTest()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			bmp = new Img() as Bitmap;
			bmpData = bmp.bitmapData;
			
			var start:int, end:int;
			start = getTimer();
			grayScale(bmpData);
			end = getTimer();
			trace(end-start, "ms");
			
			start = getTimer();
			CV.grayScale(bmpData);
			end = getTimer();
			trace(end-start, "ms");
			
			addChild(bmp);
		}
		
		private function grayScale(bmpData:BitmapData):void{
			bmpData.lock();
			for(var i:int = 0; i < bmpData.height; i++){
				for(var j:int = 0; j < bmpData.width; j++){
					var color:uint = bmpData.getPixel(j,i);
					color = ((color&0xFF) + ((color>>8)&0xFF) + ((color>>16)&0xFF))/3;
					bmpData.setPixel(j,i, color+(color<<8)+(color<<16));
				}
			}
			bmpData.unlock();
		}
	}
}

ネイティブとの連携部分

package jp.ane.sample
{
	import flash.display.BitmapData;
	import flash.external.ExtensionContext;
	import flash.utils.ByteArray;
	
	public class ANE_CV
	{
		
		private var context:ExtensionContext;
		
		public function ANE_CV()
		{
			context = ExtensionContext.createExtensionContext("jp.ane.sample.CV", null);
		}
		
		public function grayScale(bmpData:BitmapData):void{
			var ba:ByteArray = bmpData.getPixels(bmpData.rect);
			context.call("grayScale", ba, bmpData.width, bmpData.height);
			ba.position = 0;
			bmpData.setPixels(bmpData.rect, ba);
		}
	}
}

C++
dllmain.cpp

// dllmain.cpp : DLL アプリケーションのエントリ ポイントを定義します。
#include "stdafx.h"
#include <stdlib.h>

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

__declspec(dllexport) void cvExtInitializer(
    void** extDataToSet,
    FREContextInitializer* ctxInitializerToSet,
    FREContextFinalizer* ctxFinalizerToSet)
{
    *extDataToSet = NULL;
    *ctxInitializerToSet = &cvContextInitializer;
    *ctxFinalizerToSet = &cvContextFinalizer;
}

__declspec(dllexport) void cvExtFinalizer(void* extData) {
    return;
}

void cvContextInitializer(
    void* extData,
    const uint8_t* ctxType,
    FREContext ctx,
    uint32_t* numFunctionsToTest,
    const FRENamedFunction** functionsToSet)
{
    *numFunctionsToTest = 1;
 
    FRENamedFunction* func =
       (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*2);
 
    func[0].name = (const uint8_t*)"grayScale";
    func[0].functionData = NULL;
    func[0].function = &grayScale;
 
    *functionsToSet = func;
}

void cvContextFinalizer(FREContext ctx) {
	return;
}

//グレースケール化
FREObject grayScale(
    FREContext ctx,
    void* funcData,
    uint32_t argc,
    FREObject argv[])
{
	FREByteArray ba;
	int32_t w, h;

	FREAcquireByteArray(argv[0], &ba);
	FREGetObjectAsInt32(argv[1], &w);
	FREGetObjectAsInt32(argv[2], &h);

	uint32_t *p, *data = (uint32_t*)(ba.bytes);
	int r, g, b;

	p = data;

	for(int y = 0; y < h; ++y) {
		for(int x = 0; x < w; ++x) {
			r = *p >> 8 & 0xff;
			g = *p >> 16 & 0xff;
			b = *p >> 24 & 0xff;
			r = g = b = (r+g+b)/3;
			*p = b << 24 | g << 16 | r << 8;
			p++;
		}
	}

  FREReleaseByteArray(argv[0]);
  return FREObject();
}

stdafx.cpp

// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または
// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。
//

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // Windows ヘッダーから使用されていない部分を除外します。
// Windows ヘッダー ファイル:
#include <windows.h>



// TODO: プログラムに必要な追加ヘッダーをここで参照してください。
#include "FlashRuntimeExtensions.h"

extern "C" __declspec(dllexport) void cvExtInitializer(
    void** extDataToSet,
    FREContextInitializer* ctxInitializerToSet,
    FREContextFinalizer* ctxFinalizerToSet
);

extern "C" __declspec(dllexport) void cvExtFinalizer(void* extData);

void cvContextInitializer(
    void* extData,
    const uint8_t* ctxType,
    FREContext ctx,
    uint32_t* numFunctionsToTest,
    const FRENamedFunction** functionsToSet
);

void cvContextFinalizer(FREContext ctx);

FREObject grayScale(
	FREContext ctx,
	void* funcData,
	uint32_t argc,
	FREObject argv[]
);

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次の HTMLタグおよび属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>