How can I control the visual affect with Camera class?
I've checked the document:
http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/media/Camera.html
But stil开发者_高级运维l don't find info on how to control the visual affect(like lightness, saturation and so on) of my pc camera.
Is that kind of job possible with actionscript?
You can't alter the actual Camera data (there is a difference between that and what I am describing further), but it's possible to do what you want easily, after attaching the Camera object to a Video object and using the variety of transformation filters and routines from other native ActionScript classes like ColorTransform
, DisplayObject.transform.colorTransform
and DisplayObject.filters
, to alter what is displayed on the screen/memory, which, I believe, is probably what you want anyway.
To give you a real world usage example, you can adjust saturation of the camera data being displayed in your video with the following code:
/// Desaturate displayed image completely
video.filters = [ new ColorMatrixFilter(saturation_filter_matrix(0)) ];
where I have defined the methods as:
static inline var RWGT = 0.3086;
static inline var GWGT = 0.6094;
static inline var BWGT = 0.0820;
static public function brightness_filter_matrix(b: Float)
{
return [ b, 0, 0, 0, 0,
0, b, 0, 0, 0,
0, 0, b, 0, 0,
0, 0, 0, 1, 0 ];
}
static public function saturation_filter_matrix(s: Float)
{
var b = (1 - s) * RWGT;
var a = b + s;
var d = (1 - s) * GWGT;
var e = d + s;
var g = (1 - s) * BWGT;
var i = g + s;
return [ a, d, g, 0, 0,
b, e, g, 0, 0,
b, d, i, 0, 0,
0, 0, 0, 1, 0 ];
}
static public function contrast_filter_matrix(v: Float)
{
v += 1;
var r = v;
var g = v;
var b = v;
return [ r, 0, 0, 0, 128 * (1 - r),
0, g, 0, 0, 128 * (1 - g),
0, 0, b, 0, 128 * (1 - b),
0, 0, 0, 1, 0 ];
}
I also think that transform.colorTransform
may be more efficient with doing the same job, somehow I have observed that filters tend to tax Adobe Flash Player to moderate to high degree, so be advised.
The implications of the fact that you cannot change actual camera input, are that when you publish your camera across network (to Flash Media Server for instance), no matter what effects you use to display the data in your own video object, the party playing the stream will see the original unaltered data. A "workaround" would be to announce to the receiving party the exact parameters you want them to apply to their video object that is playing the stream. Assuming they apply these parameters in the same way you do for your displayed camera image, they will see your camera image the way you see it.
Note: The code is written in Haxe, but the two languages are very similar. The changes you need to be aware of are (blatant advertisement for Haxe follows :-) Float
in Haxe is Number
in ActionScript 3 for example, and Haxe uses type inference which makes it possible to omit variable types at will, letting Haxe figure it out itself (when you add two int
's what do you get? On Flash platform, you always get an int
as well.) Also AS3 does not have the concept of inlining (yet?) and so you must simply remove inline
syntax from the code, that's all.
In response to your comment regarding accessing the camera data directly, the only area I can think of where this would be an issue is if you are recording to a FMS (flash media server, Red5, wowza etc), in which case the data comes directly out of the camera and into the netstream (netStream.attachCamera(cam)
). For this there is no direct workaround, you could maybe store the brightness and contrast settings (from a filter effect) as flv metadata when you publish/stream the video, but then the person on the other end would have to decode this metadata (i.e. playback using a Flash component or something that can decode AMF data), for this see the setDataFrame
method of NetConnection
For everything else you can use the methods suggested above, take the cam, shove it into a Video
instance with video.attachCamera
and then use video.filters = [myFilter]
to apply the effect you desire. If you want to get down and dirty with the pixels you could use the draw
property of a BitmapData
object to draw the camera image from the video onto a bitmap for manipulation, you must however do this on an enterFrame
or Timer
to keep the bitmapData in sync.
var video:Video = new Video(w,h);
video.attachCamera(Camera.getCamera());
var bmd:BitmapData = new BitmapData(w,h);
bmd.draw(video);
Hope this is helps
精彩评论