Silverlight之WriteableBitmap的使用

时间:2020-12-25 19:14:04
</pre>WriteableBitmap我想大家并不陌生吧,它是一个基于内存的图像管理类,大家可以把它认为图像是一堆存储在内存中的数据,这些数据可由WriteableBitmap管理和分配。 这里我就给大家讲一些关于WriteableBitmap的一些使用技巧: 实现自绘 众所周知,目前为止,微软还没有开放自绘接口,如果你真的想在界面上自已绘制一个字符串,都有些困难呢。下面的代码正是使用WriteableBitmap来实现自绘的方案  <pre name="code" class="csharp">private void RenderString(WriteableBitmap bitmap, string stringToRender) 
{ 
TextBlock textBlock = new TextBlock(); 
textBlock.Text = stringToRender; 
//设置 font, size,等等 
bitmap.Render(textBlock, null); 
bitmap.Invalidate(); 
} 
 
怎么样,很简单吧,他是通过将TextBlock中的文本绘制到WriteableBitmap来实现的,在这里我发挥一下,那不就可以通过这个方法,来实现一个图片水印的功能么,赶快去试试吧 
顺便说一点,这里我要介绍一个更强大的开源的库writeablebitmapex,如果大家想要绘制更复杂的的图像如:点,线,曲线,阴影,形状,以及实现一些常用的图像数据处理功能,那么这个库将是大家 
最好的选择。 
图像的缩放存储 
如果你想将一张图片改变大小,那么你可以用以下的方法去实现 
 
WriteableBitmap resizedImage = new WriteableBitmap(imageToResize);//imageToResize is BitmapImage 
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication()) 
{ 
using (System.IO.IsolatedStorage.IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(fileName, FileMode.Create, isf)) 
{ 
double maxHeight = newWidth; 
double maxWidth = newHeight; 
double scaleX = 1; 
double scaleY = 1; 
if (pixHt > maxHeight) 
scaleY = maxHeight / pixHt; 
if (pixWt > maxWidth) 
scaleX = maxWidth / pixWt;


                double scale = Math.Min(scaleY, scaleX);
                int newWidth1 = Convert.ToInt32(pixWt * scale);
                int newHeight1 = Convert.ToInt32(pixHt * scale);


                resizedImage.SaveJpeg(isfs, newWidth1, newHeight1, 0, 70);
                isfs.Close();
            }
        }

 
在这里,imageToResize就是你输入的图像,你可以将它存储为目标大小的图像文件 
对控件(全屏)进行截图 
在很多应用中,如果要对当前页面进行截图,应该怎么办呢,这时WriteableBitmap就能帮助到你了。 
把页面截图,并保存到内存 
 
WriteableBitmap wb = new WriteableBitmap(UiRoot, null);//将UI页面的根元素传入,可将当面页面的截图保存到WriteableBitmap 
MemoryStream ms = new MemoryStream();


wb.SaveJpeg(ms, myWidth, myHeight, 0, 100);//保存到内存MemoryStream 
BitmapImage bmp = newBitmapImage(); //把截图转化为BitmapImage 
bmp.SetSource(ms); 
using (var isoFileStream =newIsolatedStorageFileStream("myPicture.jpg",FileMode.OpenOrCreate,IsolatedStorageFile.GetUserStoreForApplication()))
{ 
wb.SaveJpeg(isoFileStream, myWidth, myHeight,0,100); //把截图存储到独立存储
} 

 
将存储在Sql数据库的图片二进制数据载入到内存 
有些时候图片数据是以二进制数据保存到sqlite数据库中的,下面将是,如何把这些二进制数据还原成图像格式 
 
public static byte[] ConvertToBytes(String imageLocation) 
{ 
StreamResourceInfo sri = Application.GetResourceStream(new Uri(imageLocation, UriKind.RelativeOrAbsolute)); 
BinaryReader binary = new BinaryReader(sri.Stream);


    byte[] imgByteArray = binary.ReadBytes((int)(sri.Stream.Length));


    binary.Close();
    binary.Dispose();
    return imgByteArray;
}


public static WriteableBitmap ConvertToImage(Byte[] inputBytes)
{
    MemoryStream ms = new MemoryStream(inputBytes);
    WriteableBitmap img = new WriteableBitmap(400, 400);


    img.LoadJpeg(ms);


    return (img);
}


实现鼠标移动到地图上的地区,实现区域选中(白色)与未选中(蓝色)


前台 
<!--白色地图-->
        <Image x:Name="ProvinceImageM" Stretch="Fill"
               MouseLeftButtonUp="ProvinceImage_MouseLeftButtonUp"
               MouseMove="ProvinceImage_MouseMove"></Image>
        <!--蓝色地图-->
        <Image x:Name="ProvinceImage" Stretch="Fill"
               MouseLeftButtonUp="ProvinceImage_MouseLeftButtonUp"
               MouseMove="ProvinceImage_MouseMove"></Image>




后台

(主要思路是获取当前鼠标的像素,然后转换成Byte 判断RGP的值)

public void ProvinceImage_MouseMove(object sender, MouseEventArgs e)
        {
            #region  判断鼠标移动位置
            try
            {
                WriteableBitmap bitmap = null;
                Point myPoint = new Point();


                if (sender as ProvinceThumbnail != null)
                {
                    myPoint = e.GetPosition((sender as ProvinceThumbnail).ProvinceImage);
                    if (myPoint.X < 0) return; //当X小于零,图片事件会相应错误。
                    bitmap = new WriteableBitmap((sender as ProvinceThumbnail).ProvinceImage, null); // my image 图片控件名
                }
                else
                {
                    return;
                }


                if (myPoint.Y <= bitmap.PixelHeight && myPoint.X <= bitmap.PixelWidth)
                {
                    int pixelLocation = bitmap.PixelWidth * int.Parse(myPoint.Y.ToString()) + int.Parse(myPoint.X.ToString());
                    int pixel = bitmap.Pixels[pixelLocation];
                    byte[] pixBytes = BitConverter.GetBytes(pixel);


                    if (pixBytes[0] != 0 || pixBytes[1] != 0 || pixBytes[2] != 0) // 本图
                    {
                        ProvinceImage.Visibility = Visibility.Collapsed;
                        ProvinceImageM.Visibility = Visibility.Visible;
                    }
                    else if (pixBytes[0] == 0 && pixBytes[1] == 0 && pixBytes[2] == 0) //透明
                    {
                        ProvinceImage.Visibility = Visibility.Visible;
                        ProvinceImageM.Visibility = Visibility.Collapsed;
                    }
                }
            }
            catch (Exception ex)
            {
                //do nothing
            }
            #endregion
        }


附加
WriteableBitmap bitmap = new WriteableBitmap(image1,null); // image1 图片控件名
for (int y = 0; y < bitmap.PixelHeight; y++)
{ <pre name="code" class="csharp" style="color: rgb(85, 85, 85); font-size: 15px; line-height: 35px;">    for (int x = 0; x < bitmap.PixelWidth; x++)
    { 
        int pixelLocation = bitmap.PixelWidth * y + x;
        int pixel = bitmap.Pixels[pixelLocation];
        byte[] pixBytes = BitConverter.GetBytes(pixel);
        MessageBox.Show("蓝:" + pixBytes[0] + "绿:" + pixBytes[1] + "红:" + pixBytes[2] + "透明度:" + pixBytes[3]);
    } 
}