WPF图片预览之移动、旋转、缩放
RT,这个功能比较常见,但凡涉及到图片预览的都跑不了,在说自己的实现方式前,介绍一个好用的控件:Extended.Toolkit中的Zoombox,感兴趣的同学可以去搜一下这个控件,它封装了常用的预览功能。那么为什么我没用这个控件呢?因为产品不同意- -!
开始撸代码,整理一下思路先:
首先打算用一个Window来展示图片,但是QQ、微信预览图片的时候,任务栏并没有出现图标,难道用了什么黑科技?不管它,将Window的ShowInTaskbar设置为False就可以不显示在任务栏了。
继续,提到移动、旋转、缩放之类的,WPF提供了与之对应的Transform:TranslateTransform、RotateTransform、ScaleTransform,所以我们必然要使用他们仨了。怎么触发呢?那就用到事件了,移动么MouseMove,缩放么MouseWheel,旋转的话就是固定的按钮的点击事件了。另外,缩放的话可以限制一下最大和最小的缩放系数,我这边只设了缩小时如果小于系数0.3就不再缩小了,放大系数没有设置。
说一下其中的坑:
MouseWheel事件参数里会取到鼠标的Delta,这个参数不好直接用来设置缩放系数,那多少合适呢,看到别人的经验之谈,用这个Delta/3000即可。
double delta = (double)e.Delta / 3000;
ScaleTransform scale = group.Children[0] as ScaleTransform;
if (scale.ScaleX < 0.3 && scale.ScaleY < 0.3 && e.Delta < 0)
{
return;
}
scale.CenterX = this.imageControl.ActualWidth / 2;
scale.CenterY = this.imageControl.ActualHeight / 2;
scale.ScaleX += delta;
scale.ScaleY += delta;
MouseMove移动图片的时候,是可以将整个图片移到Window外面去的,这就要我们限制一下图片的移动范围了:
private void TopMove(TranslateTransform translate, Point position, Point imagePos)
{
if (scaleValue > 1.0)
{
if (mouseXY.Y - position.Y > 0.0)//up
{
double wm = winHeight - position.Y;
double im = (this.imageControl.ActualHeight - imagePos.Y) * scaleValue;
if (wm - im <= -5.0)
{
translate.Y -= mouseXY.Y - position.Y;
}
}
else
{
if (position.Y / scaleValue - imagePos.Y <= -5.0)
{
translate.Y -= mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
double iw = (this.imageControl.ActualWidth - imagePos.X) * scaleValue;
double ww = winWidth - position.X;
if (ww - iw <= -5.0)
{
translate.X -= mouseXY.X - position.X;
}
}
else
{
if (position.X / scaleValue - imagePos.X <= -5.0)
{
translate.X -= mouseXY.X - position.X;
}
}
}
else
{
if (mouseXY.Y - position.Y > 0.0)//up
{
if (position.Y / scaleValue >= imagePos.Y)
{
translate.Y -= mouseXY.Y - position.Y;
}
}
else
{
double im = (this.imageControl.ActualHeight - imagePos.Y) * scaleValue;
double wm = winHeight - position.Y;
if (im <= wm)
{
translate.Y -= mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
if (position.X / scaleValue >= imagePos.X)
{
translate.X -= mouseXY.X - position.X;
}
}
else
{
double iw = (this.imageControl.ActualWidth - imagePos.X) * scaleValue;
double ww = winWidth - position.X;
if (iw <= ww)
{
translate.X -= mouseXY.X - position.X;
}
}
}
}
稍微解释一下上面的代码,position是鼠标相对于Window的位置,imagePos是鼠标相对于图片的位置,scaleValue是图片当前的缩放比例,当图片是缩小状态(scaleValue<1)时,允许图片在整个Window里拖动,上移时,如果图片上边框触碰到了Window上边框,则不能再上移(另外3个方向原理相同),反之(scaleValue>1),只有当图片超出Window范围时才允许拖动,假设,图片上下超出了Window,则只能上下移动不能左右移动,并且,上移时,如果图片下边框触碰到了Window下边框,则不能再上移(另外3个方向原理相同)。
眼尖的同学可能注意到了上面这个方法名:TopMove,没错,这个算法只适用于图片正着放的时候的位移计算,我们不是有旋转吗,旋转了只有就不能这么算了,原因在于,imagePos始终是相对于图片来的,也就是说,如果图片旋转了90°,那么imagePos的坐标系也要旋转90°,但是我们最终要计算的是相对于Window的坐标系,所以要做相应的转换。
好了,上完整的代码:
<Window x:Class="VcreditChat.Windows.MaxPicture"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
WindowStyle="None"
AllowsTransparency="True"
Background="#82000000"
KeyDown="PicWin_KeyDown"
Loaded="PicWin_Loaded"
MouseLeftButtonDown="Window_MouseLeftButtonDown"
WindowStartupLocation="CenterScreen"
Icon="../Resources/Images/ico_48.ico"
ShowInTaskbar="False"
Closed="PicWin_Closed"
x:Name="picWin">
<Grid x:Name="outGrid">
<Grid.Resources>
<TransformGroup x:Key="transGroup">
<ScaleTransform/>
<TranslateTransform/>
<RotateTransform/>
</TransformGroup>
</Grid.Resources>
<ContentControl x:Name="picControl"
MouseLeftButtonDown="PicControl_MouseLeftButtonDown"
MouseLeftButtonUp="PicControl_MouseLeftButtonUp"
MouseMove="PicControl_MouseMove"
MouseWheel="PicControl_MouseWheel">
<Image x:Name="imageControl"
RenderTransform="{StaticResource transGroup}"
Stretch="None"
RenderOptions.BitmapScalingMode="Fant"
MouseEnter="ImageControl_MouseEnter"
MouseLeave="ImageControl_MouseLeave">
<Image.ContextMenu>
<ContextMenu>
<MenuItem Foreground="#333333" Header="复制" Click="MaxImageCopy_Click"></MenuItem>
<MenuItem Foreground="#333333" Header="另存为" Click="MaxImageSave_Click"></MenuItem>
</ContextMenu>
</Image.ContextMenu>
</Image>
</ContentControl>
<StackPanel x:Name="failedImg" VerticalAlignment="Center" Visibility="Collapsed">
<Image Source="../Resources/Images/img_failed.png" Stretch="None"></Image>
<TextBlock x:Name="failedTxt" HorizontalAlignment="Center" Foreground="White" FontSize="14" Margin="0 6 0 0"></TextBlock>
</StackPanel>
<Border Background="#393A3C" Width="30" Height="30" VerticalAlignment="Top" HorizontalAlignment="Right" MouseLeftButtonDown="Image_MouseLeftButtonDown" MouseEnter="Border_MouseEnter" MouseLeave="Border_MouseLeave">
<Grid>
<Path Data="M 8,8 L 22,22" Stroke="#FFFFFF" StrokeThickness="2"/>
<Path Data="M 22,8 L 8,22" Stroke="#FFFFFF" StrokeThickness="2"/>
</Grid>
</Border>
<Border x:Name="scalBorder" Background="#80393A3C" Width="210" Height="40" VerticalAlignment="Bottom">
<StackPanel VerticalAlignment="Center" Orientation="Horizontal" HorizontalAlignment="Center">
<Image MouseLeftButtonDown="Small_Image_MouseLeftButtonDown" Stretch="None" Source="../Resources/Images/zoom_small.png" Cursor="Hand"></Image>
<TextBlock Margin="12 0 0 0" x:Name="scalTxt" FontSize="20" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center">100%</TextBlock>
<Image Margin="12 0 0 0" MouseLeftButtonDown="Big_Image_MouseLeftButtonDown" Stretch="None" Source="../Resources/Images/zoom_big.png" Cursor="Hand"></Image>
<Path Margin="10 0 0 0" Data="M 0,2 L 0,28" Stroke="#D8D8D8" StrokeThickness="1"></Path>
<Image Margin="10 0 0 0" MouseLeftButtonDown="Rotate_Image_MouseLeftButtonDown" Stretch="None" Source="../Resources/Images/rotate.png" Cursor="Hand"></Image>
</StackPanel>
</Border>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using VcreditChat.Common;
namespace VcreditChat.Windows
{
public partial class MaxPicture : Window
{
private double picWidth = 0.0;
private double picHeight = 0.0;
private double winWidth = 0.0;
private double winHeight = 0.0;
private bool mouseDown;
private Point mouseXY;
private double scaleValue = 1.0;
private double rotateAngle = 0.0;
private string picUrl = string.Empty;
public MaxPicture(string picUrl)
{
InitializeComponent();
this.picUrl = picUrl;
System.IO.FileInfo fileInfo = new System.IO.FileInfo(picUrl);
if (fileInfo.Length<=0)
{
this.failedImg.Visibility = Visibility.Visible;
this.scalBorder.Visibility = Visibility.Collapsed;
this.failedTxt.Text = "图片过大,下载未完成。大图建议以文件方式发送!";
return;
}
BitmapSource bitmap = BitmapHelper.GetImgSource(picUrl);
if (bitmap==null)
{
this.failedImg.Visibility = Visibility.Visible;
this.scalBorder.Visibility = Visibility.Collapsed;
this.failedTxt.Text = "图片加载出错!";
return;
}
picHeight = bitmap.Height;
picWidth = bitmap.Width;
this.imageControl.Source = bitmap;
}
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
try
{
if (!mouseDown)
{
this.DragMove();
}
}
catch (Exception)
{
}
}
private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.Close();
}
private void Border_MouseEnter(object sender, MouseEventArgs e)
{
Border border = sender as Border;
border.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#DC143C"));
}
private void Border_MouseLeave(object sender, MouseEventArgs e)
{
Border border = sender as Border;
border.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#393A3C"));
}
private void PicWin_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
this.Close();
}
}
private void PicControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var img = sender as ContentControl;
if (img == null)
{
return;
}
img.CaptureMouse();
this.mouseDown = true;
this.mouseXY = e.GetPosition(img);
}
private void PicControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var img = sender as ContentControl;
if (img==null)
{
return;
}
img.ReleaseMouseCapture();
this.mouseDown = false;
}
private void PicControl_MouseMove(object sender, MouseEventArgs e)
{
var img = sender as ContentControl;
if (img == null)
{
return;
}
if (this.mouseDown)
{
if (e.LeftButton != MouseButtonState.Pressed)
{
return;
}
this.Cursor = Cursors.SizeAll;
var group = this.outGrid.FindResource("transGroup") as TransformGroup;
TranslateTransform translate = group.Children[1] as TranslateTransform;
Point imagePos = e.GetPosition(this.imageControl);
Point position = e.GetPosition(img);
int i = Convert.ToInt16(rotateAngle % 360);
switch (i)
{
case 0:
TopMove(translate, position, imagePos);
break;
case 90:
RightMove(translate, position, imagePos);
break;
case 270:
LeftMove(translate, position, imagePos);
break;
case 180:
BottomMove(translate, position, imagePos);
break;
default:
break;
}
mouseXY = position;
}
}
private void RightMove(TranslateTransform translate, Point position, Point imagePos)
{
if (scaleValue > 1.0)
{
if (mouseXY.Y - position.Y > 0.0)//up
{
if (winHeight - position.Y - (this.imageControl.ActualWidth-imagePos.X) * scaleValue <= -5.0)
{
translate.X -= mouseXY.Y - position.Y;
}
}
else
{
if (position.Y / scaleValue - imagePos.X <= -5.0)
{
translate.X -= mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
if (winWidth - position.X - imagePos.Y * scaleValue <= -5.0)
{
translate.Y += mouseXY.X - position.X;
}
}
else
{
if (position.X / scaleValue -this.imageControl.ActualHeight+ imagePos.Y <= -5.0)
{
translate.Y += mouseXY.X - position.X;
}
}
}
else
{
if (mouseXY.Y - position.Y > 0.0)//up
{
if (position.Y / scaleValue >= imagePos.X)
{
translate.X -= mouseXY.Y - position.Y;
}
}
else
{
if ((this.imageControl.ActualWidth - imagePos.X) * scaleValue <= winHeight - position.Y)
{
translate.X -= mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
if (position.X / scaleValue >=this.imageControl.ActualHeight- imagePos.Y)
{
translate.Y += mouseXY.X - position.X;
}
}
else
{
if (imagePos.Y * scaleValue <= winWidth - position.X)
{
translate.Y += mouseXY.X - position.X;
}
}
}
}
private void LeftMove(TranslateTransform translate, Point position, Point imagePos)
{
if (scaleValue>1.0)
{
if (mouseXY.Y - position.Y > 0.0)//up
{
if (winHeight - position.Y - imagePos.X * scaleValue <= -5.0)
{
translate.X += mouseXY.Y - position.Y;
}
}
else
{
if (position.Y / scaleValue - this.imageControl.ActualWidth + imagePos.X <= -5.0)
{
translate.X += mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
double iw = (this.imageControl.ActualHeight - imagePos.Y) * scaleValue;
double ww = winWidth - position.X;
if (ww - iw <= -5.0)
{
translate.Y -= mouseXY.X - position.X;
}
}
else
{
if (position.X-imagePos.Y * scaleValue <=-0.5 )
{
translate.Y -= mouseXY.X - position.X;
}
}
}
else
{
if (mouseXY.Y - position.Y > 0.0)//up
{
if (position.Y / scaleValue >= this.imageControl.ActualWidth - imagePos.X)
{
translate.X += mouseXY.Y - position.Y;
}
}
else
{
if (imagePos.X * scaleValue <= winHeight - position.Y)
{
translate.X += mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
if (position.X / scaleValue >= imagePos.Y)
{
translate.Y -= mouseXY.X - position.X;
}
}
else
{
if ((this.imageControl.ActualHeight - imagePos.Y) * scaleValue <= winWidth - position.X)
{
translate.Y -= mouseXY.X - position.X;
}
}
}
}
private void BottomMove(TranslateTransform translate, Point position, Point imagePos)
{
if (scaleValue > 1.0)
{
if (mouseXY.Y - position.Y > 0.0)//up
{
if (winHeight - position.Y - imagePos.Y * scaleValue <= -5.0)
{
translate.Y += mouseXY.Y - position.Y;
}
}
else
{
if (position.Y / scaleValue -this.imageControl.ActualHeight+ imagePos.Y <= -5.0)
{
translate.Y += mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
if (winWidth - position.X - imagePos.X * scaleValue <= -5.0)
{
translate.X += mouseXY.X - position.X;
}
}
else
{
if (position.X / scaleValue -this.imageControl.ActualWidth + imagePos.X <= -5.0)
{
translate.X += mouseXY.X - position.X;
}
}
}
else
{
if (mouseXY.Y - position.Y > 0.0)//up
{
if (position.Y / scaleValue >= this.imageControl.ActualHeight - imagePos.Y)
{
translate.Y += mouseXY.Y - position.Y;
}
}
else
{
if (imagePos.Y * scaleValue <= winHeight - position.Y)
{
translate.Y += mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
if (position.X / scaleValue >=this.imageControl.ActualWidth- imagePos.X)
{
translate.X += mouseXY.X - position.X;
}
}
else
{
if (imagePos.X * scaleValue <= winWidth - position.X)
{
translate.X += mouseXY.X - position.X;
}
}
}
}
private void TopMove(TranslateTransform translate, Point position, Point imagePos)
{
if (scaleValue > 1.0)
{
if (mouseXY.Y - position.Y > 0.0)//up
{
double wm = winHeight - position.Y;
double im = (this.imageControl.ActualHeight - imagePos.Y) * scaleValue;
if (wm - im <= -5.0)
{
translate.Y -= mouseXY.Y - position.Y;
}
}
else
{
if (position.Y / scaleValue - imagePos.Y <= -5.0)
{
translate.Y -= mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
double iw = (this.imageControl.ActualWidth - imagePos.X) * scaleValue;
double ww = winWidth - position.X;
if (ww - iw <= -5.0)
{
translate.X -= mouseXY.X - position.X;
}
}
else
{
if (position.X / scaleValue - imagePos.X <= -5.0)
{
translate.X -= mouseXY.X - position.X;
}
}
}
else
{
if (mouseXY.Y - position.Y > 0.0)//up
{
if (position.Y / scaleValue >= imagePos.Y)
{
translate.Y -= mouseXY.Y - position.Y;
}
}
else
{
double im = (this.imageControl.ActualHeight - imagePos.Y) * scaleValue;
double wm = winHeight - position.Y;
if (im <= wm)
{
translate.Y -= mouseXY.Y - position.Y;
}
}
if (mouseXY.X - position.X > 0.0)//left
{
if (position.X / scaleValue >= imagePos.X)
{
translate.X -= mouseXY.X - position.X;
}
}
else
{
double iw = (this.imageControl.ActualWidth - imagePos.X) * scaleValue;
double ww = winWidth - position.X;
if (iw <= ww)
{
translate.X -= mouseXY.X - position.X;
}
}
}
}
private void PicControl_MouseWheel(object sender, MouseWheelEventArgs e)
{
ContentControl img = sender as ContentControl;
if (img == null)
{
return;
}
Point point = e.GetPosition(img);
TransformGroup group = this.outGrid.FindResource("transGroup") as TransformGroup;
double delta = (double)e.Delta / 3000;
ScaleTransform scale = group.Children[0] as ScaleTransform;
if (scale.ScaleX < 0.3 && scale.ScaleY < 0.3 && e.Delta < 0)
{
return;
}
scale.CenterX = this.imageControl.ActualWidth / 2;
scale.CenterY = this.imageControl.ActualHeight / 2;
scale.ScaleX += delta;
scale.ScaleY += delta;
scaleValue = scale.ScaleX;
this.scalTxt.Text = Math.Ceiling(scaleValue * 100) + "%";
}
private void PicWin_Loaded(object sender, RoutedEventArgs e)
{
winWidth = this.picWin.Width;
winHeight = this.picWin.Height;
if (picWidth > winWidth || picHeight > winHeight)
{
this.imageControl.Stretch = Stretch.Uniform;
}
}
private void ImageControl_MouseEnter(object sender, MouseEventArgs e)
{
this.Cursor = Cursors.SizeAll;
}
private void ImageControl_MouseLeave(object sender, MouseEventArgs e)
{
this.Cursor = Cursors.Arrow;
}
private void MaxImageCopy_Click(object sender, RoutedEventArgs e)
{
BitmapHelper.ImageCopy(this.picUrl);
}
private void MaxImageSave_Click(object sender, RoutedEventArgs e)
{
BitmapHelper.ImageSave(this.picUrl);
}
private void PicWin_Closed(object sender, EventArgs e)
{
System.GC.Collect();
}
private void Rotate_Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
TransformGroup group = this.outGrid.FindResource("transGroup") as TransformGroup;
TranslateTransform translate = group.Children[1] as TranslateTransform;
RotateTransform rotate = group.Children[2] as RotateTransform;
translate.X = 0;
translate.Y = 0;
rotate.CenterX = this.imageControl.ActualWidth / 2;
rotate.CenterY = this.imageControl.ActualHeight / 2;
rotateAngle += 90.0;
rotate.Angle = rotateAngle;
}
private void Small_Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
ZoomImage(-0.05,-1);
}
private void Big_Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
ZoomImage(0.05,1);
}
private void ZoomImage(double delta,int type)
{
TransformGroup group = this.outGrid.FindResource("transGroup") as TransformGroup;
ScaleTransform scale = group.Children[0] as ScaleTransform;
if (type==-1)
{
if (scale.ScaleX < 0.3 && scale.ScaleY < 0.3)
{
return;
}
}
scale.CenterX = this.imageControl.ActualWidth / 2;
scale.CenterY = this.imageControl.ActualHeight / 2;
scale.ScaleX += delta;
scale.ScaleY += delta;
scaleValue = scale.ScaleX;
this.scalTxt.Text = Math.Ceiling(scaleValue * 100) + "%";
}
}
}
最后上个图吧:
WPF图片预览之移动、旋转、缩放的更多相关文章
- JS实现图片预览与等比缩放
案例仅为图片预览功能,省略图片上传步骤,框架为easyui. HTML代码: @*text-align:center;水平居中 vertical-align: middle;display: tabl ...
- 纯JS实现图片预览与等比例缩放和居中
最近做项目时有一个需求,广告位图片上传时要预览,并且要等比例缩放和居中.已经保存的广告位图片显示时也要等比例缩放和居中.我使用了下面的代码实现,不过可能有一些小问题. <!DOCTYPE HTM ...
- vue项目中图片预览旋转功能
最近项目中需要在图片预览时,可以旋转图片预览,在网上找了下,发现有一款功能强大的图片组件:viewerjs. git-hup: https://github.com/fengyuanchen/view ...
- js实现移动端图片预览:手势缩放, 手势拖动,双击放大...
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- Android 手势检测实战 打造支持缩放平移的图片预览效果(下)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39480503,本文出自:[张鸿洋的博客] 上一篇已经带大家实现了自由的放大缩小图 ...
- JS 解决 IOS 中拍照图片预览旋转 90度 BUG
上篇博文[ Js利用Canvas实现图片压缩 ]中做了图片压缩上传,但是在IOS真机测试的时候,发现图片预览的时候自动逆时针旋转了90度.对于这个bug,我完全不知道问题出在哪里,接下来就是面向百度编 ...
- previewImage.js图片预览缩放保存插件
previewImage.js好用的图片预览缩放保存插件
- 使用canvas实现图片预览、缩放(压缩)以及生成文件下载
参考 https://www.runoob.com/html/html5-canvas.html https://www.cnblogs.com/yuanzhiguo/p/8288822.html h ...
- 图片预览组件PhotoView
图片预览组件PhotoView PhotoView是一款图片预览组件,广泛应用于大图的查看.该组件支持图片手势缩放.旋转等功能.它可以很好的和ViewPager.Picasso等组件结合,实现各种复杂 ...
随机推荐
- ScrollView镶嵌listview显示不全的原因
当ScrollView镶嵌listview会显示不全,通过查看ScrollView测量高度的源码,会发现ScrollView重写了父类viewGroup的measureChildWithMargins ...
- 微信小程序之性能优化
如果做前端仅仅停留在编码和实现业务功能上面,可能进步速度会有些慢,但是如果经历了对页面的性能优化之后而且有所成绩的话那就不同了,因为你对他背后的机制进行了研究,才能做好性能优化. 做微信小程序也是一样 ...
- 洛谷 P1509 找啊找啊找GF
题目背景 "找啊找啊找GF,找到一个好GF,吃顿饭啊拉拉手,你是我的好GF.再见." "诶,别再见啊..." 七夕...七夕...七夕这个日子,对于sqybi这 ...
- nodejs一个函数实现消息队列中间件
消息队列中间件(Message Queue)相信大家不会陌生,如Kafka.RabbitMQ.RocketMQ等,已经非常成熟,在大大小小的公司和项目中也已经广泛使用. 有些项目中,如果是只使用初步的 ...
- MySQL入门很简单: 4 创建 修改删除表
1. 创建表的方法 1)创建表的语法形式 首先,选择数据库: USE 数据库名: 创建表: CREATE TABLE 表名 (属性名 数据类型 [完整性约束条件], 属性名 数据类型 [完整性约束条件 ...
- IOS tableView的性能优化(缓存池)
使用缓存池(标识类型) 1.通过 一个 标识 去 缓存池 中寻找可循环得用的cell 2.如果缓存池找不到可循环得用的cell:创建一个新的cell(给cell贴个标识) 3.给cell设置新的数据 ...
- 简单广搜,迷宫问题(POJ3984)
题目链接:http://poj.org/problem?id=3984 解题报告: 1.设置node结构体,成员pre记录该点的前驱. 2.递归输出: void print(int i) { ) { ...
- 快餐店之间插入仓库,路最短,DP,POJ(1485)
题目链接:http://poj.org/problem?id=1485 暂时我还没想出思路求路径.哈哈哈,先写一下中间步骤吧. #include <stdio.h> #include &l ...
- php开启短标签支持
打开php.ini,找到 short_open_tag = Off ,将 Off 改为 On
- Vue nodejs商城项目-项目概述
项目概况 用vue2.0 +node.js +MongonDB 做了一个商城系统 技术选型 Vue2.0+node.js+express+MongoDB+axios+vuex 构建工具 Webpack ...