类似溶液效果的颜色融合
项目中需要一个两张图能够比较理想的融合在一起,
自然想到溶质溶剂,
也没有找到其他可以使用的东西了
弄了个方法,希望能解决,但是发现处理及其缓慢,加了点优化,
要是有更好的方法就好了
--》
--》
**
* 两张图的溶解算法
* @param solute 溶质
* @param solvent溶剂
* @param strength 溶质之强度
* @param scaleNum 缩放比
* @return
*
*/
public static function DilutionColor( solute:BitmapData,
solvent:BitmapData,
strength:Number, scaleNum:Number = 1 ):BitmapData{
if( !solute || !solvent ){
return null;
}
var soluteClone:BitmapData;
var solventClone:BitmapData;
var m:Matrix;
if(scaleNum == 1){
soluteClone = solute;
solventClone = solvent;
}else{
soluteClone = new BitmapData(solute.width*scaleNum,solute.height*scaleNum, true, 0x00000000);
solventClone = new BitmapData(solvent.width*scaleNum,solvent.height*scaleNum, true, 0x00000000);
m = new Matrix();
m.scale(scaleNum,scaleNum);
soluteClone.draw( solute,m,null,null,null,true);
solventClone.draw( solvent,m,null,null,null,true);
}
//// 溶质实际像素大小
var solute_rec:Rectangle = soluteClone.getColorBoundsRect( 0xff000000,0xff000000,true);
if( solute_rec.width==0 || solute_rec.height == 0 ){
return solvent.clone();
}
var solute_vec_uint:Vector.<uint> = soluteClone.getVector(solute_rec);
///// 溶剂实际像素大小
var solvent_rec:Rectangle = solventClone.getColorBoundsRect( 0xff000000,0xff000000,true);
var solvent_vec_uint:Vector.<uint> = solventClone.getVector(solvent_rec);
var tempRec:Rectangle = solvent.rect;
var tempNum:Number = 0;
/// 扩散时候 影响的范围
var diffuseRegionRec:Rectangle = new Rectangle();
diffuseRegionRec.x = solute_rec.x - strength;
diffuseRegionRec.y = solute_rec.y - strength;
diffuseRegionRec.width = solute_rec.width + 2 * strength;
diffuseRegionRec.height = solute_rec.height + 2 * strength;
diffuseRegionRec.x = diffuseRegionRec.x < 0 ? 0 : diffuseRegionRec.x;
diffuseRegionRec.y = diffuseRegionRec.y < 0 ? 0 : diffuseRegionRec.y;
tempNum = tempRec.width - diffuseRegionRec.x;
diffuseRegionRec.width = diffuseRegionRec.width > tempNum ? tempNum : diffuseRegionRec.width;
tempNum = tempRec.height - diffuseRegionRec.y;
diffuseRegionRec.height = diffuseRegionRec.height > tempNum ? tempNum : diffuseRegionRec.height;
///// 扩散后的区域和 溶质 溶剂之间的位置的偏差
var diffuseRegion_bitmapdata:BitmapData = new BitmapData(diffuseRegionRec.width, diffuseRegionRec.height, true, 0x00000000 );
var diffuse_vec_uint:Vector.<uint> = diffuseRegion_bitmapdata.getVector( diffuseRegion_bitmapdata.rect );
var index:uint = 0;
var len:uint = diffuse_vec_uint.length;
var tx:int = 0;
var ty:int = 0;
var solute_tx:int = 0;
var solute_ty:int = 0;
var solute_len:uint = solute_vec_uint.length;
var i:uint = 0;
var j:uint = 0;
var k:int = 0;
var soluteIndex:uint = 0;
var soluteOffset:Rectangle = new Rectangle();
soluteOffset.x = solute_rec.x - diffuseRegionRec.x;
soluteOffset.y = solute_rec.y - diffuseRegionRec.y;
soluteOffset.width = solute_rec.width;
soluteOffset.height = solute_rec.height;
var solute_boo:Boolean = false;
var distance:Number = 0;
var soluteColor:uint = 0;
var solvent_tx:int = 0;
var solvent_ty:int = 0;
var solvent_index:uint = 0;
var solvent_boo:Boolean = false;
var point1:Point = new Point();
var point2:Point = new Point();
var tempWidth:uint = 0;
var tempHeight:uint =0;
var tempDistance:Number = 0;
var color:uint = 0;
var xStart:int = 0,xEnd:int = 0,yStart:int = 0,yEnd:int = 0;
var widowsRec:Rectangle;
for( index = 0; index < len; index++ ) {
tx = int( index % diffuseRegionRec.width );
ty = int( index / diffuseRegionRec.width );
//// 如果在溶质范围里面了 就以溶质内容为主
if( solute_rec.contains( tx+diffuseRegionRec.x, ty+diffuseRegionRec.y ) ){
color = getColorValue_vec_uint( solute_vec_uint, tx-soluteOffset.x, ty-soluteOffset.y, soluteOffset.width);
if( color > 0xff000000 ){
diffuse_vec_uint[ index ] = color;
continue;
}
}
////移动的窗口
widowsRec = new Rectangle(tx-strength,ty-strength,2*strength,2*strength);
widowsRec = widowsRec.intersection(soluteOffset);
///需要计算的点 和 溶质没有没有交集
if( widowsRec == null)
continue;
xStart = widowsRec.x;
xEnd = xStart + widowsRec.width;
yStart = widowsRec.y;
yEnd = yStart + widowsRec.height;
point1.x = tx;
point1.y = ty;
distance = Number.MAX_VALUE;
solute_boo = false;
solvent_boo = false;
soluteIndex = 24;
for( i = xStart; i < xEnd; i++ ){
for( j = yStart; j < yEnd; j++ ){
k = ( j - soluteOffset.y )* soluteOffset.width + (i - soluteOffset.x);
if ( (solute_vec_uint[k] ) > 0xff000000 ){
point2.x = i;
point2.y = j;
tempDistance = Point.distance(point1,point2);
if( tempDistance <= strength ){
if( tempDistance < distance ){
distance = tempDistance;
soluteIndex = k;
solute_boo = true;
}
}
}
}
}
solvent_tx = tx + diffuseRegionRec.x;
solvent_ty = ty + diffuseRegionRec.y;
if( solvent_rec.contains(solvent_tx,solvent_ty) ){
solvent_tx -= solvent_rec.x;
solvent_ty -= solvent_rec.y;
solvent_index = solvent_ty * solvent_rec.width + solvent_tx;
solvent_boo = true;
}
/////找到了扩散源
if( solute_boo && solvent_boo ){
color = solute_vec_uint[soluteIndex];
color = blendAlpha( color, 1 - distance / strength );
}else if( solute_boo ){
color = solute_vec_uint[soluteIndex];
color = blendAlpha(color, 1 - distance / strength );
}else if( solvent_boo ){
color = solvent_vec_uint[solvent_index];
color = 0;
}else{
color = 0xff000000;
}
diffuse_vec_uint[ index ] = color;
}
diffuseRegion_bitmapdata.setVector(diffuseRegion_bitmapdata.rect,diffuse_vec_uint);
var result:BitmapData = new BitmapData( solvent.width, solvent.height, true, 0x00000000 );
if( scaleNum == 1 ){
result.copyPixels( diffuseRegion_bitmapdata, diffuseRegion_bitmapdata.rect, new Point(diffuseRegionRec.x,diffuseRegionRec.y) );
}else{
m = new Matrix();
m.scale(1/scaleNum,1/scaleNum);
m.translate(diffuseRegionRec.x/scaleNum,diffuseRegionRec.y/scaleNum);
result.draw( diffuseRegion_bitmapdata, m, null,null,null,true );
result.draw( solute, null, null,null,null,true );
}
return result;
}

浙公网安备 33010602011771号