Simples utilização de WritableBitmap
Tuesday, August 18th, 2009Autor: Tiago Andrade e Silva
O Silverlight 3 introduziu o WritableBitmap que nos permite manipular os pixels directamente.
Eis um pequeno exemplo de utilização. Neste exemplo simula-se a chuva de uma televisão quando não tem emissão. Para o efeito preenche-se cada pixel da imagem com uma cor aleatória. A imagem está constantemente a ser redesenhada de modo a dar a noção da “chuva”.
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) { Screen.Width = ScreenWidth; Screen.Height = ScreenHeight; //Criaco do object writablebitmap com o tamanho indicado. bitmap = new WriteableBitmap(ScreenWidth, ScreenHeight); //Indicao de qual o elemento que ira fazer a visualizao do writable bitmap. Screen.Source = bitmap; //registar o evento para fazer o render regular CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering); }
Após esta inicialização e na entrada em cada frame redesenha-se a “chuva” ao nível do pixel:
void CompositionTarget_Rendering(object sender, EventArgs e) { var index = MaxScreen; //Pintar cada pixel while (--index > -1) { //cor aleatoria para cada pixel var color = System.Convert.ToInt32(rnd.Next(0xffffff)); bitmap.Pixels[index] = color > 0xffffff ? 0xffffff : color; } //força o bitmap a redesenhar bitmap.Invalidate(); }
Utilizando o seguinte xaml com uma imagem de uma TV para dar enquadramento:
<Grid x:Name="LayoutRoot" Background="#FFFFFFFF"> <Image x:Name="tv" Source="tv.jpg" Margin="68,29.807,72,53.193" d:LayoutOverrides="Width, Height"/> <Image x:Name="Screen" OpacityMask="{x:Null}" Margin="99,57,100,0" Opacity="1" VerticalAlignment="Top" Height="216" Width="390"/> </Grid>
O resultado é:
Fazer download do código fonte desta aplicação.
Se agora brincarmos com a chuva através da posição do rato, conseguimos criar a noção de interferências feitas pelo rato. Para isso é preciso, para além do código abaixo, adicionar o evento para apanhar o movimento do rato, criar uma variável que contem a última posição do rato e actualiza-la cada vez que o rato mexe.
//Repaint the screen regularly void CompositionTarget_Rendering(object sender, EventArgs e) { var index = MaxScreen; //Paint each bitmap pixel. while (--index > -1) { if (index % (mouseLastPos.X/2 + mouseLastPos.Y/2)+rnd.Next(20) < 15) bitmap.Pixels[index] = 0xffffff; //bitmap.Pixels[index] = Convert.ToInt32(mouseLastPos.X * mouseLastPos.Y+5000); else { //Random color for each pixel. var color = System.Convert.ToInt32(rnd.Next(0xffffff)); bitmap.Pixels[index] = color > 0xffffff ? 0xffffff : color; } } //force bitmap repaint bitmap.Invalidate(); }