怎么将表格和word标题和表格距离距离调近些

In response to theprevious post about the Visual Layer in position a Tweet flooded in
In my previous post, I’d used the composition APIs to draw some spinning rectangles whereas this question was about filling those rectangles with images and so I thought I’d bend the code that I’d written to render some images.
It’s not quite as easy as it sounds – the Visual Layer talks in terms of visuals being painted with brushes and so it initially seems natural to expect that there would be some kind of ‘image brush’ to do this for you.
However, as I found in myinitial post on this topic, I don’t think that’s the case and it’s perhaps right that it isn’t the case. The composition APIs are perhaps more to do with composing things that have already been drawn than they are to do with drawing things in the first place.
So, how does a rasterizer that can draw content plug in to the composition APIs and paint a visual with what’s been drawn?
I think that the way this works (or at least one way) is to get hold of a
CompositionSurfaceBrush
which renders to an
ICompositionSurface
but the docs under those 2 hyperli
Note, ICompositionSurface is exposed in Native code only, hence LoadImage method is implemented in native code.
and the MSDN docs refer to a
“ LoadImage ” function to bring in images. However, that “LoadImage” function is one that you won’t find anywhere in the APIs – it’s implemented in the C++ code that you’ll find in the
composition samples on GitHub in this Toolkit code and the samples all seem to use this mechanism of painting visuals with images.
I didn’t necessarily want to include that bunch of C++ code every time that I wanted to draw an image and so I thought that I would use a different means to get a CompositionSurfaceBrush from an image and it’s very similar to some code that I wrote in my first post around position.
I brought in Win2D via the Win2D.uwp package because there’s some support in there for rendering content with Win2D by being able to create a
CompositionGraphicsDevice
and then using that to create a drawing surface.
My early steps then in trying to use that to render an image (from a StorageFile )
using Microsoft.Graphics.C
using Microsoft.Graphics.
using System.Threading.T
using Windows.F
using Windows.Graphics.DirectX;
using Windows.Graphics.I
using Windows.Storage.S
class CompositionImageBrush : IDisposable
private CompositionImageBrush()
public CompositionBrush Brush
return (this.drawingBrush);
void CreateDevice(Compositor compositor)
this.graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(
compositor, CanvasDevice.GetSharedDevice());
void CreateDrawingSurface(Size drawSize)
this.drawingSurface = this.graphicsDevice.CreateDrawingSurface(
DirectXPixelFormat.B8G8R8A8UIntNormalized,
DirectXAlphaMode.Premultiplied);
void CreateSurfaceBrush(Compositor compositor)
this.drawingBrush = compositor.CreateSurfaceBrush(
this.drawingSurface);
public async static Task&CompositionImageBrush& FromImageStreamAsync(
Compositor compositor,
IRandomAccessStream stream,
Size drawSize)
CompositionImageBrush brush = new CompositionImageBrush();
brush.CreateDevice(compositor);
stream.Seek(0);
var decoder = await BitmapDecoder.CreateAsync(stream);
using (var softwareBitmap = await decoder.GetSoftwareBitmapAsync(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied))
brush.CreateDrawingSurface(drawSize);
brush.DrawSoftwareBitmap(softwareBitmap, drawSize);
brush.CreateSurfaceBrush(compositor);
return (brush);
void DrawSoftwareBitmap(SoftwareBitmap softwareBitmap, Size drawSize)
using (var drawingSession = CanvasComposition.CreateDrawingSession(
this.drawingSurface))
using (var bitmap = CanvasBitmap.CreateFromSoftwareBitmap(drawingSession.Device,
softwareBitmap))
// I've made the drawing surface the same size as the visual on screen
// and so I'm now going to draw this bitmap to that surface at the
// same size too which means that I'm stretching it at this point
// whereas a smarter thing might be to let the Stretch property on
// the brush itself stretch it.
drawingSession.DrawImage(bitmap,
new Rect(0, 0, drawSize.Width, drawSize.Height));
public void Dispose()
// TODO: I'm unsure about the lifetime of these objects - is it ok for
// me to dispose of them here when I've done with them and, especially,
// the graphics device?
this.drawingBrush.Dispose();
this.drawingSurface.Dispose();
this.graphicsDevice.Dispose();
CompositionGraphicsDevice graphicsD
CompositionDrawingSurface drawingS
CompositionSurfaceBrush drawingB
I’m not 100% sure that I have that right but it means that I can now ‘walk up’ to this CompositionImageBrush class that I’ve made and grab a brush from it for an image that I have in a file and it’s going to use Win2D to render that image at the size specified onto a drawing surface that can then be used to paint a visual.
With that in place, I added a pic
and then I reworked the code that I had from the previous post. My MainPage.xaml UI
x:Class=&App287.MainPage&
xmlns=&/winfx/2006/xaml/presentation&
xmlns:x=&/winfx/2006/xaml&
xmlns:local=&using:App287&
xmlns:d=&/expression/blend/2008&
xmlns:mc=&http://schemas.openxmlformats.org/markup-compatibility/2006&
mc:Ignorable=&d&&
Background=&red&&
&TextBlock
x:Name=&txtCount& /&
&/Viewbox&
Background=&Transparent&
PointerReleased=&OnPointerReleased&
SizeChanged=&OnCanvasSizeChanged&
x:Name=&drawCanvas&/&
&/Grid&&/Page&
and I reworked the interface that I wrote to ‘abstract’ the difference between a XAML implementation and a Composition implementation. I
using System.Threading.T
using Windows.F
using Windows.S
using Windows.UI.Xaml.C
interface IDrawCanvasImages
void InitialiseWithCanvas(Canvas canvas);
Task SetImageFileAndDrawSizeAsync(StorageFile imageFile, Size drawSize);
void DrawImage(int x, int y);
void ClearImages();
and so here there’s a method to set the Canvas to be drawn to, then there’s one to set up the image to be drawn and the dimensions that it’s to be drawn it. Then there’s a method to draw an individual image and another to clear all the images.
As in the previous post, I wrote the code behind my XAML file in ter
using System.Threading.T
using Windows.F
using Windows.S
using Windows.UI.X
using Windows.UI.Xaml.C
using Windows.UI.Xaml.I
public sealed partial class MainPage : Page
public MainPage()
this.InitializeComponent();#if VISUAL_DRAWING
this.drawer = new VisualImageDrawer();#else
this.drawer = new XamlImageDrawer();#endif // XAMLDRAWING
this.drawer.InitialiseWithCanvas(this.drawCanvas);
this.timer = new DispatcherTimer();
this.timer.Interval = TimeSpan.FromMilliseconds(10);
this.timer.Tick += OnTimerT
this.timer.Start();
void OnTimerTick(object sender, object e)
this.txtCount.Text = (++this.ticks).ToString();
async void OnPointerReleased(object sender, PointerRoutedEventArgs e)
this.rectangleCount *= 4;
await RedrawAsync();
async void OnCanvasSizeChanged(object sender, SizeChangedEventArgs e)
await this.InitialiseForNewSizeAsync();
await this.RedrawAsync();
async Task InitialiseForNewSizeAsync()
var file = await StorageFile.GetFileFromApplicationUriAsync(
new Uri(&ms-appx:///Images/kermit.png&));
var fullWidth = this.drawCanvas.ActualWidth /
var fullHeight = this.drawCanvas.ActualHeight /
this.drawSize = new Size(fullWidth, fullHeight);
await this.drawer.SetImageFileAndDrawSizeAsync(
this.drawSize.Width * (1 - SPACING_FACTOR),
this.drawSize.Height * (1 - SPACING_FACTOR)));
async Task RedrawAsync()
this.drawer.ClearImages();
await this.InitialiseForNewSizeAsync();
var horizontalSpacing = SPACING_FACTOR * this.drawSize.W
var verticalSpacing = SPACING_FACTOR * this.drawSize.H
var sidelength = this.S
for (int i = 0; i & i++)
for (int j = 0; j & j++)
this.drawer.DrawImage(
(int)((i * this.drawSize.Width) + (horizontalSpacing / 2)),
(int)((j * this.drawSize.Height) + (verticalSpacing / 2)));
int Sidelength
return ((int)Math.Sqrt(this.rectangleCount));
static readonly float SPACING_FACTOR = 0.25f;
Size drawS
DispatcherT
IDrawCanvasI
int rectangleCount = 1;
and wrote a little base class to pick up a tiny bit o
using System.Threading.T
using Windows.F
using Windows.S
using Windows.UI.Xaml.C
abstract class ImageDrawerBase : IDrawCanvasImages
public abstract void ClearImages();
public abstract void DrawImage(int x, int y);
protected abstract Task SetImageFileAsync(StorageFile imageFile);
protected Canvas DrawCanvas
protected Size DrawSize
public virtual void InitialiseWithCanvas(Canvas canvas)
this.DrawCanvas =
public Task SetImageFileAndDrawSizeAsync(StorageFile imageFile, Size drawSize)
this.DrawSize = drawS
return (this.SetImageFileAsync(imageFile));
before implementing this in a XAML renderer where the vast majority of the code is the same as
using System.Threading.T
using Windows.F
using Windows.S
using Windows.UI.Xaml.C
using Windows.UI.Xaml.M
using Windows.UI.Xaml.Media.A
using Windows.UI.Xaml.Media.I
using Windows.UI.Xaml.S
class XamlImageDrawer : ImageDrawerBase
public override void ClearImages()
this.DrawCanvas.Children.Clear();
protected override async Task SetImageFileAsync(StorageFile imageFile)
using (var stream = await imageFile.OpenReadAsync())
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
this.FillBrush = new ImageBrush()
ImageSource = bitmapImage,
Stretch = Stretch.Fill
public override void DrawImage(int x, int y)
Rectangle rectangle = new Rectangle()
Width = this.DrawSize.Width,
Height = this.DrawSize.Height,
Fill = FillBrush
Canvas.SetLeft(rectangle, x);
Canvas.SetTop(rectangle, y);
AddSpinAnimationXaml(rectangle);
this.DrawCanvas.Children.Add(rectangle);
static void AddSpinAnimationXaml(Rectangle rectangle)
RotateTransform transform = new RotateTransform();
rectangle.RenderTransform =
rectangle.RenderTransformOrigin = new Point(0.5d, 0.5d);
DoubleAnimation angleAnimation =
new DoubleAnimation()
From = 0.0d,
angleAnimation.EasingFunction = new SineEase();
Storyboard.SetTarget(angleAnimation, transform);
Storyboard.SetTargetProperty(angleAnimation, &Angle&);
DoubleAnimation opacityAnimation =
new DoubleAnimation()
From = 0.0d,
opacityAnimation.EasingFunction = new SineEase();
Storyboard.SetTarget(opacityAnimation, rectangle);
Storyboard.SetTargetProperty(opacityAnimation, &Opacity&);
Storyboard storyBoard = new Storyboard();
storyBoard.Duration = TimeSpan.FromSeconds(1);
storyBoard.RepeatBehavior = RepeatBehavior.F
storyBoard.Children.Add(angleAnimation);
storyBoard.Children.Add(opacityAnimation);
storyBoard.Begin();
ImageBrush FillB
and in a position renderer that’s using the CompositionImageBrush from the previous code snippet and is perhaps around 50% different code from what I had
using System.N
using System.Threading.T
using Windows.S
using Windows.UI.Xaml.C
using Windows.UI.Xaml.H
class VisualImageDrawer : ImageDrawerBase
public override void InitialiseWithCanvas(Canvas canvas)
base.InitialiseWithCanvas(canvas);
var canvasVisual = ElementCompositionPreview.GetElementVisual(
base.DrawCanvas);
this.containerVisual = positor.CreateContainerVisual();
this.rotationAnimation = positor.CreateScalarKeyFrameAnimation();
this.rotationAnimation.InsertKeyFrame(0.0f, 0.0f);
this.rotationAnimation.InsertKeyFrame(1.0f, 360.0f);
this.rotationAnimation.Duration = TimeSpan.FromSeconds(1);
this.rotationAnimation.IterationBehavior = AnimationIterationBehavior.F
this.opacityAnimation = positor.CreateScalarKeyFrameAnimation();
this.opacityAnimation.InsertKeyFrame(0.0f, 0.0f);
this.opacityAnimation.InsertKeyFrame(1.0f, 1.0f);
this.opacityAnimation.Duration = TimeSpan.FromSeconds(1);
this.opacityAnimation.IterationBehavior = AnimationIterationBehavior.F
ElementCompositionPreview.SetElementChildVisual(this.DrawCanvas,
this.containerVisual);
public override void ClearImages()
this.containerVisual?.Children.RemoveAll();
public override void DrawImage(int x, int y)
var rectangleVisual = positor.CreateSpriteVisual();
rectangleVisual.Offset = new Vector3(x, y, 0);
rectangleVisual.Size = new Vector2(
(float)this.DrawSize.Width, (float)this.DrawSize.Height);
rectangleVisual.CenterPoint = new Vector3(
(float)(this.DrawSize.Width / 2), (float)(this.DrawSize.Height / 2), 0);
rectangleVisual.Brush = this.imageBrush.B
rectangleVisual.StartAnimation(&RotationAngleInDegrees&, this.rotationAnimation);
rectangleVisual.StartAnimation(&Opacity&, this.opacityAnimation);
containerVisual.Children.InsertAtBottom(rectangleVisual);
protected async override Task SetImageFileAsync(StorageFile imageFile)
this.imageBrush?.Dispose();
using (var stream = await imageFile.OpenReadAsync())
this.imageBrush = await CompositionImageBrush.FromImageStreamAsync(
this.DrawSize);
ScalarKeyFrameAnimation opacityA
ScalarKeyFrameAnimation rotationA
ContainerVisual containerV
CompositionImageBrush imageB
With that all in place, how does this run? I spun up the XAML based rendering (below is 16 kermits);
Initially, the app reports 30 frames per second and the system compositor reports 60 and that stays pretty constant until I reach 1024 kermits – i.e. at 1024 kermits I was seeing the app reporting 16fps and the system compositor was reporting 60.
My interpretation of that is that I’m taxing the UI thread too much.
At 4096 kermits the app was reporting around 3fps and the system (compositor) was again reporting 60fps.
With the Visual based rendering (i.e. where the compositor is doing the image drawing, the animation of the opacity and the animation of the rotation) I see that initially the performance counters report 30fps for the app and 60fps for the system and that seems to stay constant up to 16384 kermits and then things go a little crazy as I try and step to 65536 kermits.
So, that’s another little experiment with the Visual layer – the code for it is here if you want to download and the main thing for me is that I probably picked up some re-usable code for painting visuals with images here.
无相关信息
最新教程周点击榜
微信扫一扫&&&& 一直知道在
.geos包里面有一个Rectangle对象却很少用过。无意中试用了一下发现可用的地方还很广。所以一冲动把现在的项目中的很多地方都改成了Rectangle判断了。
一:屏幕滚屏
中最常做的一项工作,一般的思路是map.x++ map.y++,然后随时判断map是否走到了头。
中我用了一张的图片来说明两种方式:
一般的做法如下:判断每一步是否超过边界如果超过边界则等于边界。
var map:Loader=new
var speed:int=7; //移动速度
map.load (new URLRequest(&2.jpg&));
map.contentLoaderInfo.addEventListener (PLETE,oncomplete);
addChild (map);
function oncomplete (evt:Event)
  stage.addEventListener (KeyboardEvent.KEY_DOWN,onkeydown);
function onkeydown2(evt:KeyboardEvent)
switch (evt.keyCode)
  case Keyboard.LEFT :
 & &if (map.x+7&0) map.x+=7;
& && &else map.x=0;
& & case Keyboard.RIGHT :
 & & if (map.x-7&stage.stageWidth-map.width)& &map.x-=7;
& && &else map.x=stage.stageWidth-map.width
  case Keyboard.UP :
& &  if (map.y+7&0) map.y+=7;
& && &else map.y=0;
  case Keyboard.DOWN :
& &  if (map.y-7&stage.stageHeight-map.height) map.y-=7;
& && &else map.y=stage.stageHeight-map.height
使用Rectangle的方法,见如下代码
var map:Loader=new Loader(); //地图容器
var rec:R //当前显示区域的范围
var maxRec:R //地图的矩形范围
var speed:int=7;
map.load (new URLRequest(&2.jpg&));
map.contentLoaderInfo.addEventListener (PLETE,oncomplete);
addChild (map);
function oncomplete (evt:Event)
maxRec=map.getBounds(map);//以自己的坐标系返回矩形
rec=new Rectangle(0,0,800,600);//显示的范围
map.scrollRect=//确定地图的可显示范围
stage.addEventListener (KeyboardEvent.KEY_DOWN,onkeydown);
function onkeydown (evt:KeyboardEvent)
rec=map.scrollR
switch (evt.keyCode)
& &case Keyboard.LEFT :
& & rec.x-=7;
& &case Keyboard.RIGHT :
& & rec.x+=7;
& &case Keyboard.UP :
& & rec.y-=7;
& &case Keyboard.DOWN :
& & rec.y+=7;
if(rec.x&0) rec.x=0;
else if(rec.x&maxRec.width-rec.width) rec.x=maxRec.width-rec.
if(rec.y&0) rec.y=0;
else if(rec.y&maxRec.height-rec.height) rec.y=maxRec.height-rec.
//if(maxRec.containsRect(rec)) 如果你无需十分精确可以关闭以上4行,把这一句打开这一句是利用了矩形的包含关系,如果移除则不包含
map.scrollRect=
两种方式的比较:
上相差不大,不过使用Rectangel的好处是利用显示对象的scrollRect
可以把区域之外的内容不显示出来。
注意事项:scrollRect的增量方向正好与物体的相反,可以想象为一个是移动物体,一个是移动屏幕。
应用二:找出屏幕外围的显示对象。
基本思路:
将Rectangle对象的坐标系设置为屏幕坐标系,利用DisplayObject.getBounds(stage)返回其他物体在屏幕坐标系中的位置,然后利用Rectangle对象的相交测试方法检测(有点类似于碰撞检测)
以下是一个例子
var rec:Rectangle = new Rectangle(0, 0, ShareData.SCENEWIDTH, ShareData.SCENEHEIGHT);
& & for (var i = 0; i & gameContainer.numC i++)
& &&&var build = gameContainer.getChildAt(i);
& &&&if(build.getBounds(stage).intersects(rec))
& && &build.visible =
& && &ShareData.visualList[build.name]=
& && &build.visible =
& && &if(ShareData.visualList[build]!=null)
& && &delete ShareData.visualList[build];
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:752228次
积分:13924
积分:13924
排名:第671名
原创:571篇
转载:505篇
评论:64条
(1)(1)(1)(3)(6)(4)(1)(4)(5)(17)(4)(10)(5)(11)(3)(10)(4)(7)(3)(5)(6)(12)(5)(1)(1)(8)(2)(6)(20)(27)(13)(29)(9)(6)(1)(1)(4)(8)(25)(17)(4)(1)(1)(2)(6)(11)(57)(62)(37)(12)(9)(11)(5)(63)(46)(34)(65)(117)(74)(37)(48)(11)(8)(2)(3)(1)(1)(4)(1)(1)(1)(41)

我要回帖

更多关于 latex 表格标题距离 的文章

 

随机推荐