参加比赛的作品,开发周期一个月,使用了 Wafer2 框架,后台采用腾讯云提供的 Node.js SDK 接入对象存储 API ,前端核心代码实现了类似于图片编辑器的功能,支持图片和文字的移动、旋转、缩放、生成预览图以及编辑状态的保存,动画部分采用 CSS 动画实现小程序中的模态输入框部分使用了自己封装的 InputBox 组件代码已移除 AppId 等敏感信息,可自行添加自己的 AppId 和 AppSecret 以配置后台环境,实现登录测试,详细添加方法见下文「使用方法」,若本地运行可通过修改 app.json 文件中 page 字段的顺序来查看不同页面微信小程序定制需求请联系作者微信:aweawds (注明来意)效果展示      使用方法首先点击右上角 Star ʕ •ᴥ•ʔ获取Demo代码执行 git clone https://github.com/goolhanrry/Weapp-Demo-LemonJournal.git或 点击此处 下载最新版本的代码解压后在微信开发者工具中打开 Weapp-Demo-LemonJournal 文件夹即可如需进行登录测试,还要执行以下步骤准备好自己的 AppId 和 AppSecret(可在微信公众平台注册后获取)在 project.config.json 的 appid 字段中填入 AppId在 /client/utils/util.js 中相应位置填入 AppId 和 AppSecret在微信开发者工具中重新导入整个项目,上传后台代码后编译运行即可核心代码组件的移动、旋转和缩放主要思路是把  标签(对应图片)和  标签(对应文字)封装在同一个自定义组件  中,通过对外暴露的 text 变量是否为空来进行条件渲染,然后绑定 onTouchStart() 、onTouchEnd() 和 onTouchMove() 三个事件来对整个组件的位置、角度、大小、层级以及 “旋转” 和 “移除” 两个按钮的行为进行操作onTouchStart: function (e) {     // 若未选中则直接返回     if (!this.data.selected) {         return     }     switch (e.target.id) {         case 'sticker': {             this.touch_target = e.target.id             this.start_x = e.touches[0].clientX * 2             this.start_y = e.touches[0].clientY * 2             break         }         case 'handle': {             // 隐藏移除按钮             this.setData({                 hideRemove: true             })             this.touch_target = e.target.id             this.start_x = e.touches[0].clientX * 2             this.start_y = e.touches[0].clientY * 2             this.sticker_center_x = this.data.stickerCenterX;             this.sticker_center_y = this.data.stickerCenterY;             this.remove_center_x = this.data.removeCenterX;             this.remove_center_y = this.data.removeCenterY;             this.handle_center_x = this.data.handleCenterX;             this.handle_center_y = this.data.handleCenterY;             this.scale = this.data.scale;             this.rotate = this.data.rotate;             break         }     } }, onTouchEnd: function (e) {     this.active()     this.touch_target = ''     // 显示移除按钮     this.setData({         removeCenterX: 2 * this.data.stickerCenterX - this.data.handleCenterX,         removeCenterY: 2 * this.data.stickerCenterY - this.data.handleCenterY,         hideRemove: false     })     // 若点击移除按钮则触发移除事件,否则触发刷新数据事件     if (e.target.id === 'remove') {         this.triggerEvent('removeSticker', this.data.sticker_id)     } else {         this.triggerEvent('refreshData', this.data)     } }, onTouchMove: function (e) {     // 若无选中目标则返回     if (!this.touch_target) {         return     }     var current_x = e.touches[0].clientX * 2     var current_y = e.touches[0].clientY * 2     var diff_x = current_x - this.start_x     var diff_y = current_y - this.start_y     switch (e.target.id) {         case 'sticker': {             // 拖动组件则所有控件同时移动             this.setData({                 stickerCenterX: this.data.stickerCenterX   diff_x,                 stickerCenterY: this.data.stickerCenterY   diff_y,                 removeCenterX: this.data.removeCenterX   diff_x,                 removeCenterY: this.data.removeCenterY   diff_y,                 handleCenterX: this.data.handleCenterX   diff_x,                 handleCenterY: this.data.handleCenterY   diff_y             })             break         }         case 'handle': {             // 拖动操作按钮则原地旋转缩放             this.setData({                 handleCenterX: this.data.handleCenterX   diff_x,                 handleCenterY: this.data.handleCenterY   diff_y             })             var diff_x_before = this.handle_center_x - this.sticker_center_x;             var diff_y_before = this.handle_center_y - this.sticker_center_y;             var diff_x_after = this.data.handleCenterX - this.sticker_center_x;             var diff_y_after = this.data.handleCenterY - this.sticker_center_y;             var distance_before = Math.sqrt(diff_x_before * diff_x_before   diff_y_before * diff_y_before);             var distance_after = Math.sqrt(diff_x_after * diff_x_after   diff_y_after * diff_y_after);             var angle_before = Math.atan2(diff_y_before, diff_x_before) / Math.PI * 180;             var angle_after = Math.atan2(diff_y_after, diff_x_after) / Math.PI * 180;             this.setData({                 scale: distance_after / distance_before * this.scale,                 rotate: angle_after - angle_before   this.rotate             })             break         }     }     this.start_x = current_x;     this.start_y = current_y; }编辑状态的保存一篇手帐包含的组件类型包括 sticker(软件自带的贴纸)、image(用户上传的图片)和 text(自定义文字)三种,全部保存在一个如下格式的 json 对象中,每个独立组件都包含了一个不重复的 id 以及相关的信息,保存时由客户端生成该对象并编码成 json 字符串存储在数据库,恢复编辑状态时通过解析 json 字符串获得对象,再由编辑页面渲染{     "backgroundId": "5",                                        背景图id     "assemblies": [         {             "id": "jhjg",                                       组件id             "component_type": "image",                          组件类型(自定义图片)             "image_url": "https://example.com/jhjg.png",        图片地址             "stickerCenterX": 269,                              中心横坐标             "stickerCenterY": 664,                              中心纵坐标             "scale": 1.7123667831396403,                        缩放比例             "rotate": -3.0127875041833434,                      旋转角度             "wh_scale": 1,                                      图片宽高比             "z_index": 19                                       组件层级         },         {             "id": "gs47",             "component_type": "text",                           组件类型(文字)             "text": "test",                                     文字内容             "stickerCenterX": 479,             "stickerCenterY": 546,             "scale": 1.808535318980528,             "rotate": 29.11614626607893,             "z_index": 10         },         {             "id": "chjn",             "component_type": "sticker",                        组件类型(贴纸)             "sticker_type": "food",                             贴纸类型             "sticker_id": "1",                                  贴纸id             "image_url": "https://example.com/weapp/stickers/food/1.png",             "stickerCenterX": 277,             "stickerCenterY": 260,             "scale": 1.3984276885130673,             "rotate": -16.620756913892055,             "z_index": 5         }     ] }
2025-08-09 09:39:27 6.81MB 开源项目
1
悉Photoshop的人都知道,PSD文件是Photoshop的默认文件格式,据我所知,在Photoshop CS2之前的版本好像有提供PSD源文件的预览功能,但是后来的版本里面就没有了,这对于经常使用Photoshop的人来说实在是太不方便了。本人深爱PS,也经常使用Photoshop这个东西,目前Photoshop最新版本是CS5版本,很好很强大。
2025-08-05 14:37:18 229KB ai格式和psd合适预览缩略图补丁
1
标题中的“一款直接能预览TGA图片的软件”指的是一个专门设计用于查看TGA(Truevision TGA,真视图图象文件)格式图像的应用程序。TGA是一种图形文件格式,常见于早期的计算机图形和游戏产业,因为它支持无损压缩并且可以存储alpha通道,适合创建和编辑动画。这款软件的出现是为了满足用户在不借助复杂图形处理软件的情况下快速浏览TGA文件的需求。 描述中的“很实用的小软件,直接预览tga等图片的缩略图”强调了软件的实用性,它不仅能够显示TGA文件,还可能支持其他类型的图片格式,并且提供了缩略图功能,让用户在不打开完整文件的情况下就能大致了解图片内容,这对于管理大量图像文件来说非常方便。 从标签“TGA 软件 图片”我们可以推断出,这个软件的主要功能是与图像处理相关的,特别是对TGA格式的支持。它是一个独立的应用,专门针对处理和查看图像,尤其是TGA格式的图像。 在提供的压缩包子文件列表中,我们有以下内容: 1. **PictInst.exe**:这很可能是软件的可执行文件,用户可以通过运行这个文件来安装和启动该图片预览软件。 2. **安装步骤.pdf**:这份文档应该包含了安装软件的具体步骤,帮助用户顺利地将程序添加到他们的电脑中。 3. **使用说明.txt**:这是一个文本文件,很可能包含了软件的使用指南和操作教程,帮助用户理解和掌握软件的各项功能。 4. **安装说明.txt**:与安装步骤.pdf类似,这个文件可能提供了额外的安装指引或注意事项。 5. **欧普软件园_打造最全免费软件和安卓游戏下载基地.url**:这是一个网站链接,指向一个提供免费软件和安卓游戏下载的平台,可能与软件的来源或推荐下载渠道有关。 这款软件为用户提供了便捷的TGA图片预览功能,同时可能兼容其他常见的图像格式。通过安装步骤文档和使用说明,用户可以轻松地在自己的设备上安装并掌握这款软件的使用。而作为在欧普软件园这样的平台上提供的资源,它可能是免费的,面向广大需要查看TGA图像的用户。
2025-07-31 17:07:39 2.78MB
1
在IT行业中,Spring Boot是一个非常流行的Java开发框架,它简化了Spring应用的初始搭建以及开发过程,提供了大量的自动配置选项,使得开发者可以快速构建高效、生产级别的应用。本项目"file-online-preview-master.zip"显然是一个关于Spring Boot实现文件在线预览的示例,下面将详细解释其中涉及的关键知识点。 我们需要理解什么是文件预览。文件预览是指用户在不下载文件到本地的情况下,通过浏览器或其他客户端工具查看文件内容。这对于提高用户体验和保护服务器资源非常重要。在Web环境中,这通常涉及到多种技术,如HTML5、JavaScript、Web Workers、以及各种Web组件。 在Spring Boot中实现文件预览,首先需要一个文件服务模块,用于处理文件的上传、存储、检索等操作。这通常会涉及到Spring Boot的`MultipartFile`接口,以及文件存储的策略,如本地存储、云存储(如阿里云OSS、AWS S3)等。开发者可能会使用Spring Boot的`StorageService`或`FileService`等自定义服务来封装这些操作。 为了实现在线预览,我们需要处理不同类型的文件。常见的文件类型有文本、图片、PDF、Office文档(Word、Excel、PPT)、音视频等。每种类型可能需要不同的处理方式。例如,图片和PDF可以直接通过浏览器的内置支持来预览,而Office文档则可能需要借助第三方库(如Apache POI、Spire.Office)来转换成HTML或者PDF格式。 在本项目中,可能使用了Spring MVC的Controller来处理HTTP请求,通过`@RequestMapping`注解定义路由,`@ResponseBody`将处理结果作为HTTP响应的主体。对于文件访问,可能通过`Resource`或`StreamingResponseBody`来提供文件流,以避免一次性加载整个文件到内存中。 此外,安全是在线预览的重要考量。为了防止恶意访问,需要对文件路径进行验证,确保只有合法的文件才能被预览。可以使用Spring Security进行权限控制,只允许已认证的用户访问特定文件。 前端部分,项目可能使用了HTML、CSS和JavaScript,可能还引入了诸如Bootstrap、jQuery或Vue.js这样的前端框架,以提供友好的用户界面和交互。文件预览可能利用了HTML5的`