类似溶液效果的颜色融合

项目中需要一个两张图能够比较理想的融合在一起,

自然想到溶质溶剂,

也没有找到其他可以使用的东西了

弄了个方法,希望能解决,但是发现处理及其缓慢,加了点优化,

要是有更好的方法就好了

--》

--》

 

    **
		 * 两张图的溶解算法
		 * @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;
		}        

  

 

posted @ 2014-07-03 02:10  jalps  阅读(210)  评论(0)    收藏  举报