iPaint






4.90/5 (8投票s)
不是普通的绘画应用
引言
绘画很有趣,绘画很有娱乐性,绘画也是社交性的。iPaint 是一种新的绘画方式,iPaint 也是一个音乐作曲家。你不是在绘画,而是在创作绘画。
用途与概念
iPaint 可以供朋友和家人用于娱乐。
iPaint 的主要功能是绘画,它同样也是一个不错的乐器,这只是一个附带效应。iPaint 的主要目的是让家人和朋友的绘画变得有趣。通过集成“家庭云”,iPaint 将绘画变成家庭绘画。
背景
有很多绘画应用,那么 iPaint 有什么不同之处呢?我鼓励你观看这个 视频,然后你就会有答案。iPaint 旨在提供独特的体验。
最独特之处在于音乐。你不仅绘画,还可以创作音乐。使用 iPaint 绘画是一种绝佳的体验。
开发方法
目标平台:一体机电脑
类别:娱乐
我正在使用 WPF 构建这个应用程序。我将使用一体机电脑来优化它以适应大屏幕尺寸,并**利用触控笔**作为印章,当在屏幕上按下时,它将在触摸区域填充颜色。
项目状态
我已经将工作流程分为三个部分。
第一部分
基本功能将在第一部分完成。
状态:已完成;
第二部分
增加视觉吸引力。增加光泽和铬色。
状态:进行中;
第三部分
增加在线功能。
状态:设计阶段;
未来:
我计划将其移植到 Unity 并发布到所有平台。由于我还在 Unity 中开发一款游戏,我每天对 Unity 的了解都在增加,我对使用 Unity 构建 iPaint 的信心也随之增强。
Unity 比 WPF 这样的演示框架提供了更强大的功能。Unity 的工作量更大,但你获得的权力也更大。移植到 Unity 是未来的计划,因为这是一项大工程,现在无法完成。如果我尝试,我就会错失良机。
特点
简单绘画
iPaint 提供了一个虚拟画布供您绘画。iPaint 支持多点触控,手指数量没有上限。
颜色填充
除了传统的绘画功能外,还有颜色填充。iPaint 包含许多素描,用户可以在其中填充颜色。
参考绘画
在此模式下,用户会看到一幅参考画,他的任务是复制它。用户可以通过临摹其他优秀画家的作品来学习绘画并培养创造力。
创新功能
iPaint 与众不同之处在于以下功能
协作
你可以与其他人合作一起绘画,无需实体在场即可共同创作。你可以通过互联网使用 iPaint Cloud 进行绘画。
iPaint 保存与继续
你的画作保存在你的设备上,你可以随时继续修改。你也可以锁定一幅画,以防止他人修改或删除。
云存储
你所有的画作都保存在云端,可以在你的所有设备上访问。你可以在一台设备上开始一幅新画,在另一台设备上继续,然后在另一台完全不同的设备或平台上修改,或者在移动中用手机进行修改!
绘画录制与回放
观看自己的创作过程!!
你的画作会被录制并保存,你可以随时回放这些画作,向朋友展示你是如何创作出杰作的,每一笔,每一个颜色,每一段音乐都被录制并回放。
家庭墙
通过家庭墙,你可以访问家人的画作,也可以复制任何一位家人的画作并进行修改。通过家庭墙,你可以了解家人在 iPaint 上画了什么。家庭墙充当家庭的社交网络。你还可以在绘画时与家人聊天。
计划在协作时增加应用内视频通话。
音乐
iPaint 将两项最具创造性、最激动人心的任务——绘画和音乐——融为一体。
你不是在绘画,你是在创作绘画。iPaint 为绘画增添了音乐的触感。当你绘画时,你创作一个音符;当你填充颜色时,你创作一个持续音。这就好像你在一体化地绘画和创作音乐。
查看 演示,了解 iPaint 中音乐与绘画的融合。
视觉效果
iPaint 充满了视觉效果,在绘画时能带来平静和成就感。这些视觉效果为在虚拟画布上绘画增添了微妙的质感。这些视觉效果有助于建立成就感,因为最终的画作无论用户的绘画技巧如何,都会很漂亮。
动态色彩
颜色是动态的,当你绘画时,颜色会美妙地变化,创作出杰作。
下面是一幅用 iPaint 原型和动态颜色绘制的画。颜色在任何时候都没有手动更改过,全都是动态的。
滑移颜色填充
你不需要频闪器来填充颜色。只需将屏幕按住你想填充颜色的点,颜色就会像从你的手指流到屏幕一样在屏幕上扩散。
直观的颜色选择器
在 iPaint 中改变颜色非常方便。调色板是一个带滑块的圆形管。你滑动管子来选择所需的颜色。
128 种乐器
iPaint 有大约 128 种乐器可供选择。从大钢琴到电吉他,iPaint 应有尽有。
使用特定于平台的特色功能
触控笔
触控笔用于填充颜色甚至绘画。
27 英寸大尺寸触摸屏
一体机电脑的大尺寸提供了宽阔的绘画区域。
iPaint 利用宽阔的屏幕尺寸提供了一个大的画布,并支持多点触控。同时绘画的人数没有限制。
环绕声扬声器
高品质的环绕声扬声器将产生优美的音乐。对用户的耳朵有益;)
演示
使用代码
绘画应用有三个主要功能。
- 绘画
- 播放声音
- 处理社交功能
绘画代码
在画布上绘制线条。
我使用路径来绘制线条。
你可以查看 这个 教程,了解如何构建一个简单的绘画应用。代码是从那里获取的。我已根据我的需要进行了修改。
private PathFigure _pathFigure; // the list of stroke points
private bool _isOnCanvas;
private Path _path = new Path();
private Color _color = Colors.Black;
private const float _penWidth = 3.0f; // pen width for drawing the stroke
///
/// Seal the object.
///
///
/// To improve performance, Seal replaces the list with fixed array.
///
public void Freeze()
{
if (_pathFigure != null)
_pathFigure.Freeze();
}
///
/// Indicate if we can add nore points to the stroke
///
public bool IsFrozen
{
get
{
return _pathFigure.IsFrozen;
}
}
///
/// Add the complete stroke
///
/// the canvas that hold all figures
public void AddToCanvas(Canvas canvas)
{
if (_isOnCanvas)
return;
_isOnCanvas = true;
PathGeometry pathGeometry = new PathGeometry();
pathGeometry.Figures = new PathFigureCollection() { _pathFigure };
_path.StrokeThickness = _penWidth;
_path.Data = pathGeometry;
canvas.Children.Add(_path);
}
///
/// Access to the property stroke color
///
public Color Color
{
get
{
return _color;
}
set
{
_color = value;
_path.Stroke = new SolidColorBrush(_color);
}
}
///
/// Access to the property stroke ID
///
public int Id { get; set; }
///
/// Adds a point to the stroke.
///
/// point to be added to the stroke
public void Add(Point pt)
{
if (_pathFigure != null && IsFrozen)
throw new InvalidOperationException("This object is frozen");
if (_pathFigure == null)
{
_pathFigure = new PathFigure();
_pathFigure.IsClosed = false;
_pathFigure.StartPoint = pt;
_pathFigure.Segments = new PathSegmentCollection();
}
else
{
_pathFigure.Segments.Add(new LineSegment(pt, true));
}
}
播放声音的代码
我使用 MIDI for .NET 库来播放声音。我在新线程中播放每个音符,以便多个音符可以同时播放。我让线程休眠一秒钟,然后关闭 MIDI 播放器,这样音符就会播放一秒钟然后关闭。
MDI for .NET 提供了一个 MidiPlayer 类型的静态对象,你用它来播放声音。在播放任何声音之前,你必须先打开 MIDI 播放器。你可以通过调用 MidiPlayer.OpenMidi() 来做到这一点。默认情况下,MidiPlayer 带有 127 个通道(乐器)。程序更改用于更改通道、音量等。你通过调用 play 和一个 NoteOn 对象来播放音符,其中 NoteOn 对象包含一个 delta(初始延迟)、通道(一个字节值)、音符(一个字符串,如“C0”)和音量(一个字节值)。
new Thread(() =>
{
MidiPlayer.OpenMidi();
MidiPlayer.Play(new ProgramChange(0, 1, channel));
MidiPlayer.Play(wheel);
MidiPlayer.Play(new NoteOn(delta, 1, note, vol));
Thread.Sleep(1000);
MidiPlayer.Play(new NoteOff(delta, 1, note, vol));
MidiPlayer.CloseMidi();
}).Start();
处理社交功能的代码
我使用 SignalR 进行通信,并将绘画推送到连接的成员。SignalR 需要托管在某个地方才能工作。我使用 Windows Azure 来托管 SignalR,并作为所有绘画的云存储。
我将绘画保存在 XML 中,存储所有播放过的点、颜色和音乐的时间线,这些数据稍后会被上传到服务器或用于回放绘画。
构建主页。
主页是一个绘画作品的幻灯片。构建背景很有趣。
背景是由许多带有随机颜色的椭圆堆叠在一起形成的,以产生模糊生动的背景。构建该背景的代码。
椭圆绘制在名为“CanvasBackground”的画布上。
int x=-30,y=-30;
for (int i = 0; i < width/15*width/30; i++)
{
Ellipse ellipse = new Ellipse();
ellipse.Width = ellipse.Height = (width / 30) - radiusRandom.Next(0, height / 100);
ellipse.Fill = GetRandomColor();
ellipse.Opacity =0.7;
ellipse.Effect = new BlurEffect() { Radius = 15 };
Canvas.SetTop(ellipse, y);
Canvas.SetLeft(ellipse, x);
_backgroundCircles[i]=(ellipse);
CanvasBackground.Children.Add(ellipse);
x = x + width / 90;
if (x > width)
{
x = -30;
y = y + height / 20;
}
if (y > height)
y = 0;
}
为了让事情变得有趣,我对背景做了一些动画。通过随机选择一些椭圆,我改变它们的颜色、不透明度或模糊度,这使得背景动态而不是无聊的静态。代码:我使用一个 DispatchTimer 每 100 秒滴答一次。
private void animateBackground(object sender, EventArgs e)
{
while (currentStack.Count <= 10)
{
currentStack.Add(_backgroundCircles[ellipseRandom.Next(_backgroundCircles.Length)]);
}
foreach (Ellipse ellipse in currentStack)
{
AnimateEllipse(ellipse);
}
if (removelRanodm.Next(10) == 2)
{
currentStack.RemoveAt(removelRanodm.Next(10));
}
}
private void AnimateEllipse(Ellipse ellipse)
{
int what = funtcionRandom.Next(3);
switch (what)
{
case 0:
ellipse.Fill = GetRandomColor();
break;
case 1:
ellipse.Opacity = opacityRandom.Next(10) / 10f;
break;
case 2:
BlurEffect effect = ellipse.Effect as BlurEffect;
effect.Radius = radiusRandom.Next(20) / 20f;
break;
default:
break;
}
}
还有一点,由于椭圆数量众多,加载主页需要一些时间。我的做法是在后台加载页面,同时显示另一个启动屏幕。我使用一个隐藏了导航栏的 NavigationWindow。
后台加载页面的代码。
Page thePage=(Page)Application.LoadComponent(new Uri("/Pages/Home.xaml", UriKind.Relative)); Action action = () => { ((NavigationWindow)Application.Current.MainWindow).Navigate(thePage); if (MainNavigationWindow != null) MainNavigationWindow.ShowsNavigationUI = false; }; Application.Current.Dispatcher.BeginInvoke(action, DispatcherPriority.Normal);
关注点
在开发这款应用时,我发现自己不是一个音乐家。我试图同时处理很多音符,直到我意识到我做不到,用户也做不到。我将音符数量从 600 个减少到 300 个。我一开始不太愿意这样做,但出乎意料的是,这增加了乐趣。
历史
[2013.07.28] - iMuzik 诞生时带有某些绘画效果,但未能保留。
[2013.07.29] - 改进了音符,去掉了刺耳的音符。
[2013.07.30] - 将音乐应用转变为绘画应用。iPaint 诞生。
[2013.07.31] - 添加了家庭墙,并将 iPaint 转变为家庭应用。
[2013.08.01] - 添加了一些不错的绘画效果,如火花、滑移。
[2013.08.02] - 提高了应用的性能。减少了内存和 CPU 消耗。
[2013.09.01] - 原型完成。