V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
arden
V2EX  ›  程序员

关于绘画 App 画完一幅画后能够重新播放整个绘画的过程

  •  
  •   arden · 2016-03-06 20:40:47 +08:00 · 5372 次点击
    这是一个创建于 3188 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在 AppStore 上看到一个叫 涂手 的 App ,玩了一下感觉蛮有意思的,很想了解下这个 App 的一个技术问题,就是当自己画玩一幅画发布出去之后,这个平台可以让大家能够播放别人在画这幅画的整个流程,也就是能够自动播放这幅画的绘画流程,不知道这个技术是如何实现的,有人了解这个技术点吗?

    第 1 条附言  ·  2016-03-06 21:12:36 +08:00
    还有一点就是分享到朋友圈后,在浏览器里也可以直接播放整个绘画流程。刚开始我以为是录的视频,但是看了他们的 html 源代码后,感觉不是录的视频。
    36 条回复    2016-03-08 21:37:39 +08:00
    linhua
        1
    linhua  
       2016-03-06 20:46:23 +08:00
    1.录像 数据量大
    2.重现用户的操作 数据量小
    em70
        2
    em70  
       2016-03-06 20:53:18 +08:00 via iPhone
    Ctrl+z
    Ctrl+y
    JiShuTui
        3
    JiShuTui  
       2016-03-06 20:57:58 +08:00
    不懂 iOS 开发,我猜是否可以这样,每个笔划(或者每隔 N 秒)保存一个 png ,然后播放图片
    arden
        4
    arden  
    OP
       2016-03-06 21:09:09 +08:00
    https://itunes.apple.com/cn/app/tu-shou-nao-dong-da-kai-tu/id973367549?mt=8
    就是这个 App ,有熟悉这个技术的朋友过来一起讨论讨论下。
    abelyao
        5
    abelyao  
       2016-03-06 21:22:19 +08:00
    记录你的操作轨迹,数据量很小的,比如 X 点到 Y 点(仅是例子)
    重播的时候直接按顺序重新添加到画布上,大概猜测是 SVG 吧
    楼主可以放一个画好之后的重播 URL 上来我们研究研究
    acros
        6
    acros  
       2016-03-06 21:25:25 +08:00
    应该和魔兽 3 录像类似的方法吧。关键帧记录关键数据。
    acros
        7
    acros  
       2016-03-06 21:31:22 +08:00
    录像是肯定不可能的。绘画时肯定有很多撤销操作,录像里面不用存下来,但是做成一个个指令就很好处理了。
    arden
        8
    arden  
    OP
       2016-03-06 21:34:04 +08:00
    @abelyao http://www.toshow.com/shared/work/7t34iuwfms41pHpxPodB9A==?from=singlemessage&isappinstalled=1
    这个我是画好的重播链接,不过直接在电脑上用浏览器打开没用,得用手机浏览器打开。
    arden
        9
    arden  
    OP
       2016-03-06 21:36:32 +08:00
    @acros 对,应该不是录像,我测试过了。我画的时候做了一些撤消操作,但是重播的时候并没有播出来。
    WildCat
        10
    WildCat  
       2016-03-06 22:05:42 +08:00 via iPhone
    WWDC 15 关于 Value Type 的这个 Session 讲了 PhotoShop 对于编辑历史的类似实现,基本原理很简单,不过没有上下文还是不在这里说了。

    http://devstreaming.apple.com/videos/wwdc/2015/414sklk5h2k3ki3/414/414_building_better_apps_with_value_types_in_swift.pdf?dl=1

    从第 158 页开始就是讲的这个内容。
    arden
        11
    arden  
    OP
       2016-03-06 22:13:31 +08:00
    刚找了下资料好像有两种方式:
    1 、记录绘画的路径数据,然后自动播放重绘,但是不太清楚,这个路径数据要怎么记录合适,因为 x/y 是不停的在变换的,那么记录的时候要实时记录吗?
    2 、可以从生成的 svg 图片来自动重播。
    xiaofami
        12
    xiaofami  
       2016-03-06 22:16:06 +08:00
    openCanvas 有回放功能,可以了解一下。
    ibireme
        13
    ibireme  
       2016-03-06 22:29:14 +08:00   ❤️ 2
    @arden

    记录手指在屏幕上的触摸点、时间点、画笔设置,这样就行了。回放的时候,时间点可以调节一下,让回放速度显得快一些。浏览器显示是用 Canvas 绘制的。。

    下面是你给的链接里那个签名的 JSON 数据:

    {"status":1,"result":{"imagejson":{"date":"1457265559665","count":2,"path":[{"w":150,"c":"FF000000","p":[{"x":80,"y":168.32},{"x":102.48,"y":154.56},{"x":128.72,"y":138.32},{"x":154.96,"y":123.28},{"x":182.48,"y":107.04},{"x":200,"y":97.04},{"x":211.2,"y":90.8},{"x":212.48,"y":104.56},{"x":180,"y":148.32},{"x":144.96,"y":213.28},{"x":117.44,"y":272.08},{"x":100,"y":320.8},{"x":90,"y":360.8},{"x":81.2,"y":392.08},{"x":78.72,"y":409.52},{"x":76.24,"y":423.28},{"x":76.24,"y":410.8},{"x":83.68,"y":380.8},{"x":103.68,"y":339.52},{"x":131.2,"y":297.04},{"x":163.68,"y":254.56},{"x":202.48,"y":217.04},{"x":234.96,"y":187.04},{"x":258.72,"y":167.04},{"x":278.72,"y":157.04},{"x":292.48,"y":155.76},{"x":302.48,"y":190.8},{"x":291.2,"y":260.8},{"x":270,"y":314.56},{"x":246.24,"y":357.04},{"x":224.96,"y":377.04},{"x":204.96,"y":382.08},{"x":177.44,"y":374.56},{"x":158.72,"y":344.56},{"x":147.44,"y":304.56},{"x":144.96,"y":270.8},{"x":144.96,"y":223.28},{"x":147.44,"y":178.32},{"x":154.96,"y":142.08},{"x":158.72,"y":123.28},{"x":156.24,"y":137.04},{"x":151.2,"y":175.76},{"x":150,"y":222.08},{"x":150,"y":257.04},{"x":150,"y":292.08},{"x":150,"y":309.52},{"x":163.68,"y":285.76},{"x":172.48,"y":218.32}]},{"w":150,"c":"FF000000","p":[{"x":224.96,"y":65.76},{"x":228.72,"y":85.76},{"x":228.72,"y":115.76},{"x":218.72,"y":168.32},{"x":196.24,"y":222.08},{"x":174.96,"y":267.04},{"x":158.72,"y":290.8},{"x":147.44,"y":300.8},{"x":162.48,"y":272.08},{"x":187.44,"y":248.32},{"x":204.96,"y":230.8},{"x":216.24,"y":219.52},{"x":220,"y":235.76},{"x":192.48,"y":287.04},{"x":161.2,"y":357.04},{"x":144.96,"y":412.08},{"x":132.48,"y":464.56},{"x":127.44,"y":503.28},{"x":127.44,"y":528.32},{"x":127.44,"y":540.8},{"x":151.2,"y":519.52},{"x":163.68,"y":463.28},{"x":177.44,"y":414.56},{"x":188.72,"y":389.52},{"x":203.68,"y":374.56},{"x":216.24,"y":370.8},{"x":231.2,"y":372.08},{"x":242.48,"y":407.04},{"x":243.68,"y":449.52},{"x":243.68,"y":492.08},{"x":226.24,"y":520.8},{"x":210,"y":532.08},{"x":188.72,"y":532.08},{"x":174.96,"y":527.04},{"x":172.48,"y":504.56},{"x":180,"y":464.56},{"x":213.68,"y":420.8},{"x":258.72,"y":369.52},{"x":293.68,"y":329.52},{"x":321.2,"y":292.08},{"x":337.44,"y":273.28},{"x":348.72,"y":264.56},{"x":358.72,"y":299.52},{"x":347.44,"y":347.04},{"x":340,"y":398.32},{"x":338.72,"y":438.32},{"x":338.72,"y":468.32},{"x":338.72,"y":485.76},{"x":351.2,"y":487.04},{"x":363.68,"y":447.04},{"x":380,"y":395.76},{"x":402.48,"y":350.8},{"x":430,"y":315.76},{"x":450,"y":299.52},{"x":464.96,"y":293.28},{"x":478.72,"y":293.28},{"x":488.72,"y":322.08},{"x":488.72,"y":357.04},{"x":466.24,"y":399.52},{"x":451.2,"y":425.76},{"x":443.68,"y":438.32},{"x":454.96,"y":430.8},{"x":487.44,"y":388.32},{"x":523.68,"y":323.28},{"x":550,"y":253.28},{"x":564.96,"y":208.32},{"x":572.48,"y":178.32},{"x":576.24,"y":160.8},{"x":572.48,"y":197.04},{"x":560,"y":245.76},{"x":547.44,"y":294.56},{"x":542.48,"y":330.8},{"x":540,"y":357.04},{"x":548.72,"y":322.08},{"x":570,"y":265.76},{"x":600,"y":219.52},{"x":634.96,"y":188.32},{"x":671.2,"y":163.28},{"x":696.24,"y":149.52},{"x":711.2,"y":139.52},{"x":716.24,"y":127.04},{"x":702.48,"y":127.04},{"x":687.44,"y":130.8},{"x":671.2,"y":153.28},{"x":662.48,"y":187.04},{"x":656.24,"y":230.8},{"x":652.48,"y":278.32},{"x":652.48,"y":319.52},{"x":663.68,"y":339.52},{"x":680,"y":349.52},{"x":697.44,"y":353.28},{"x":718.72,"y":353.28},{"x":688.72,"y":359.52},{"x":634.96,"y":402.08},{"x":583.68,"y":445.76},{"x":550,"y":480.8},{"x":534.96,"y":503.28},{"x":547.44,"y":517.04},{"x":602.48,"y":510.8},{"x":656.24,"y":489.52},{"x":702.48,"y":465.76},{"x":738.72,"y":449.52},{"x":756.24,"y":434.56},{"x":756.24,"y":415.76},{"x":728.72,"y":402.08},{"x":698.72,"y":398.32},{"x":668.72,"y":398.32},{"x":647.44,"y":409.52},{"x":634.96,"y":457.04},{"x":634.96,"y":525.76},{"x":646.24,"y":590.8},{"x":670,"y":635.76},{"x":700,"y":655.76}]}]}}}
    Mutoo
        14
    Mutoo  
       2016-03-06 22:34:11 +08:00   ❤️ 1
    以前经常在闪吧看高手画画(暴露年龄了)
    arden
        15
    arden  
    OP
       2016-03-06 22:34:54 +08:00
    @ibireme 谢谢。
    arden
        16
    arden  
    OP
       2016-03-06 22:36:21 +08:00
    @xiaofami openCanvas 在哪有介绍?
    lwhite
        17
    lwhite  
       2016-03-07 00:41:54 +08:00
    开源软件里面有个 Drawpile ,它自带了一个过程录制和编辑功能。
    http://drawpile.net/help/recording

    它的那个录像是录制事件的,可以生成一个可编辑的小文件或者视频来还原整个多人协作绘画过程,你可以看一下它的代码是咋做的的, opencanvas 好像是做不到对每一个事件的编辑的。
    cosven
        18
    cosven  
       2016-03-07 01:53:05 +08:00
    个人感觉:
    如果采用录像的话,感觉不太现实,画一幅画,一般来说,都有大半天或者几天

    不用录像的方法的话: 像 SAI 或者 PS ,他们的历史纪录往往都是有限的,应该是有技术上的限制。
    cosven
        19
    cosven  
       2016-03-07 01:55:03 +08:00
    @cosven 所以感觉好神奇
    bytelee
        20
    bytelee  
       2016-03-07 07:48:07 +08:00
    我做过两种:
    1.直接录像,但是要做好 cache ,及时写入文件,保证 memory
    2.直接保存路线,然后通过 keyframe animation 来重现这些动作。

    后者方式比较好. 当然 楼上的那个 json 最好再加入一个 duration 属性。 :)
    manhere
        21
    manhere  
       2016-03-07 07:53:37 +08:00 via iPhone
    十年前 Discuz 论坛就有涂鸦回复功能了,基于 flash ,
    基本就是 @ibireme 说的原理。
    sablib
        22
    sablib  
       2016-03-07 08:53:10 +08:00
    刚好实现过…
    arden
        23
    arden  
    OP
       2016-03-07 08:53:50 +08:00
    @sablib 能介绍下实现原理和方法吗?
    sablib
        24
    sablib  
       2016-03-07 09:00:17 +08:00
    @arden 手指在屏幕上移动的时候记录坐标 xy ,以及 duration 。
    最后所有的数据都拿到之后用 cashapelayer 的 path 根据 duration 做动画。最后同步效果还挺好的。
    当然我是 iOS 所以是说的这样。
    arden
        25
    arden  
    OP
       2016-03-07 09:06:15 +08:00
    @sablib xy 我能理解,可是 duration 这个东西怎么记录?上一次 xy 到下一次 xy 的间隔时间?
    sablib
        26
    sablib  
       2016-03-07 09:11:46 +08:00
    @arden 对,你可以只记录一下当前时间最后再来算这个 duration 。或者在这里就把 duration 记录下来。
    如果要把画的时候的速度体现出来的话,这个 duration 是必须的。
    最后重现的时候是要根据这个来画的。我是用了 cakeyframeanimation 来做,当然动画的时候是一次对一笔做动画。
    arden
        27
    arden  
    OP
       2016-03-07 09:16:10 +08:00
    @sablib 那意思就是说 xy-xy 的记录,越频繁,间隔时间越短,就越逼真了?
    stackboom
        28
    stackboom  
       2016-03-07 09:22:20 +08:00
    1.贝塞尔曲线
    2.把点记录成一条 Json 字符串
    3.浏览器 Canvas 绘图
    sablib
        29
    sablib  
       2016-03-07 09:27:12 +08:00
    @arden 最后那个 path 肯定不能直接把那些点连起来这样,不然的话画的稍微快一些就都变成折线了。
    karnaugh
        30
    karnaugh  
       2016-03-07 09:49:54 +08:00
    感觉跟魔兽争霸和 Dota2 的录像机制一样.一场 40 多分钟的录像文件只需要几个 MB.
    zoezoe
        31
    zoezoe  
       2016-03-07 11:06:38 +08:00
    codeyung
        32
    codeyung  
       2016-03-07 11:08:38 +08:00
    mark
    arden
        33
    arden  
    OP
       2016-03-07 11:12:33 +08:00
    @zoezoe 分析过他们的技术了,这个不是通过录制来实现的。应该是通过 @sablib 提的方案。
    arden
        34
    arden  
    OP
       2016-03-08 16:33:16 +08:00
    @sablib 我刚抓了一下涂手 App 在 iphone 和 android 上的数据包,他们在重放的时候调用了
    http://resource.toshow.com/work/json/1457424788!9qaILd1wlE5XI6x2ANNsf6oVb1ItWot5.txt
    这个地址获得数据,然后根据这个内容再重放的,可是这个文件打开的全都是一些看不懂的字符串。
    sablib
        35
    sablib  
       2016-03-08 20:58:40 +08:00
    @arden 对数据做了加密吧。
    arden
        36
    arden  
    OP
       2016-03-08 21:37:39 +08:00
    @sablib 有这种可能,可是为什么 ios/android 请求的时候已经加密了,但是手机浏览器请求的时候得到的还是用的 json 明文数据。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1525 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 17:09 · PVG 01:09 · LAX 09:09 · JFK 12:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.