Willis

Willis 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织 www.xiebruce.top/ 编辑
编辑

php开发者

个人动态

Willis 回答了问题 · 2020-10-26

Yii2添加request的baseUrl后加载的资源url也会加上这个baseUrl导致加载的不对

好吧,经过大量的搜索、仔细的查看文档以及Q群问网友,最后还是我自己解决了,如下代码所示,在components里面添加一个assetManager(必须小写开头),在里面就可以重置baseUrl

'components' => [
    'assetManager' => [
        //after settting components.request.baseUrl='/admin', the assets url will automatically add "/admin" to its url
        //to avoid this, we can set the asset baseUrl in components.assetManager.baseUrl, set it to '/assets'
        'baseUrl' => '/assets',
    ],
    'request' => [
        'csrfParam' => '_csrf-backend',
        //All requests will add "/admin",e.g:
        //www.example.com/controller/action will change to
        //www.example.com/admin/controller/action
        'baseUrl' => '/admin',
    ],
    // other configs....
],

关注 1 回答 1

Willis 提出了问题 · 2020-10-24

Yii2添加request的baseUrl后加载的资源url也会加上这个baseUrl导致加载的不对

我的是Advanced版本,我frontend和backend是单独用不同域名的,由于怕权限管理里面跟前台的路由有相同的,所以就在后台的路径里添加个/admin

具体是在backend的main.phpcomponents里添加baseUrl => /admin添加,添加后,页面是可以访问的,就是url多了个admin,比如从backend.example.com/controller/action变成backend.example.com/admin/controller/action

'components' => [
    'request' => [
        'csrfParam' => '_csrf-backend',
        //All requests will add "/admin",e.g:
        //backend.example.com/controller/action will change to
        //backend.example.com/admin/controller/action
        'baseUrl' => '/admin',
    ],
],

但问题是,assets url也加了这个admin,导致无法加载
image.png

我试了改这个文件backend/assets/AppAsset.php里的$baseUrl,但是无论我怎么修改,它完全不起作用(没设置'baseUrl' => '/admin'的时候设置这个是有用的)

<?php

namespace backendassets;

use yiiwebAssetBundle;

/**
 * Main backend application asset bundle.
 */
class AppAsset extends AssetBundle {
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
        'css/site.css',
    ];
    public $js = [
    
    ];
    public $depends = [
        'yiiwebYiiAsset',
        'yiibootstrapBootstrapAsset',
    ];
}

另外我发现在views页面中用registerJsFile()添加的js,就不会添加/admin,就能正常加载

$this->registerJsFile('plugins/ImageViewer/imageviewer.min.js', ['position' => View::POS_END, 'depends'=>JqueryAsset::class]);

image.png

所以想问一下大佬们,怎样设置能让assets不添加这个/admin?感觉这个文件backend/assets/AppAsset.php里应该可以设置才对呀。

关注 1 回答 1

Willis 赞了文章 · 2020-10-01

双击事件(dblclick)时,不触发单击事件(click)

事件绑定中,执行双击事件(dblclick)时能触发两次单击事件(click)。即一个标签元素(如button等),如果元素同时绑定了单击事件(click)和双击事件(dblclick),那么执行单击事件(click)时,不会触发双击事件(dblclick), 执行双击事件(dblclick)时却会触发两次单击事件(click)。

先看一下点击事件的执行顺序:

单击(click):mousedown,mouseout,click;
双击(dblclick):mousedown,mouseout,click , mousedown,mouseout,click,dblclick;

在单击的时候不会执行双击,但是双击的时候会执行两次单击再执行双击事件。
解决的思路:要想双击时不执行单击事件,就使用定时器清除掉两个单击事件,留下一个双击事件。

如下实现,使用setTimeout

<button onclick="single(event)" ondblclick="double(event)">按钮</button>

var time = 200;
var timeOut  = null;

function single (e) {
    clearTimeout(timeOut); // 清除第一个单击事件
    timeOut= setTimeout(function () {
        console.log('单击');
        // 单击事件的代码执行区域
        // ...
    }, time)
}
function double (e) {
    clearTimeout(timeOut); // 清除第二个单击事件
    console.log('双击')
    // 双击的代码执行区域
    // ...
}

然后现在,单击按钮打印“单击”,双击按钮打印“双击”。

关于 time=200,大家知道js的事件循环机制,点击事件会添加一个任务队列。time=0, 也会添加一个任务队列。那么time=0与time=200有什么区别呢?

因为第一次单击事件后,主线程没有任何任务,就会立马执行这个单击事件的任务。待第二次单击的时候,假设距离第一次单击事件是150ms, 如果你的定时器小于150ms, 那么第一次的任务队列就会执行完。
要想不执行第一次的任务队列,那么定时器时间间隔就必须大于两次单击的时间间隔了。这样才能清除第一次的单击事件,所以,这个200是酌情值,大于间隔就行。

第一次单击任务不执行了,是被定时器延时,然后第二次点击的时候给清除了。那么第二次点击事件呢?
在两次单击之后,会立马执行一个双击事件,双击事件的一开头就把这个第二次点击事件给清除了。至此两个单击时间全部被清除了,大功告成。

这就是双击事件的大概过程。

查看原文

赞 5 收藏 0 评论 3

Willis 发布了文章 · 2020-06-02

PHP分片上传文件到又拍云对象存储

本文参加又拍云原创技术征文活动

注册&实名认证

注册我就不说了,大家自行前往又拍云注册就行。

注册之后需要实名认证,否则无法使用,但由于我已经实名认证了(当时没截图),网上也很难找到截图,我找了一张很模糊的,不过还是能看清的

认证方式:支付宝芝麻信用有700分以上选支付宝芝麻信用认证,没有的话选人工(选人工应该要上传手持身份证的照片)
所属行业:我的是博客,所以我选的是门户网站→博客
网站/产品:就填你的网站名称(暂时没有就随便想一个)
网站地址:写你自己搭建的博客域名,没有的话用csdn,博客园,新浪博客之类的博客地址,再没有的话好像也可以不写
个人名称:写你的姓名(跟身份证要一样)
身份证号码:如实填写,否则无法通过实名认证

创建存储桶

登录后,点击页面右上角的控制台,然后选择云产品→云存储
Xnip2020-06-02_13-02-15.jpg

点击右上角创建一个服务(在这里叫服务,其它云一般叫“存储桶”,英文“bucket”)
-w1179

按下图填写,其中加速按你的需求,但如果选择全球加速,价格肯定比国内加速贵;操作员如果你之前没有就需要新建并授权,因为调用api需要一个账号密码,但这个账号密码并不是你注册又拍云的那个账号密码,而是要在这里新建一个,叫“操作员”

测试操作员账号及默认域名

又拍云的对象存储是支持直接使用ftp登录的,这里我使用filezilla登录(其它ftp工具也类似)。

打开filezilla,如下图所示,点击左上角的“Site Manager”图标(也可直接点击菜单FileSite Manager)进入以下界面,然后按下图填写参数

如果ftp能连接上,也能上传文件,说明操作员账号没啥问题,连不上可能是前面忘了授权,可以点击右上角用户名→账户管理
-w461

然后点击操作员→管理,查看是否已经给了这个操作员权限,如果没有给,则给它加上权限,然后再试,应该就没问题了
-w1199

另外,我们还可以在网页上上传文件
-w1174

创建一个服务后,又拍云默认会给我们一个测试域名,域名结构为”https://服务名.test.upcdn.net“,其实也可以在控制台中看到,点击上图中的“配置”→选择域名管理选项卡(实际上默认就是该选项卡)→滚动到最底下即可看见送的测试域名。

使用php分片上传文件

REST API文档,其中并行式断点续传和串行式断点续传,就是分片上传了
-w1016

不过又拍云有写好的php-sdk,就不用我们自己写这个,直接传参就行。

创建一个文件夹UploadToUpyun,在终端中进入该文件夹,使用composer安装sdk(没有composer命令请自行安装,都0202年了应该都有吧?)

composer require upyun/sdk

安装完成后,在UploadToUpyun文件夹中创建一个index.php,代码如下,注释已经写的非常清楚,填上你的参数即可正常运行,相信没有人不会

<?php
require 'vendor/autoload.php';

use Upyun\Config;
use Upyun\Upyun;

//你自己创建的服务的名称
$serviceName = 'YOUR_SERVICE_NAME';
//操作员账号
$operator = 'YOUR_OPERATOR_NAME';
//操作员密码
$password = 'YOUR_OPERATOR_PASSWORD';
//要上传到哪个目录下
$directory = '/UploadToUpyun/test/';
//要上传的文件的绝对路径(请换成你电脑上一个图片文件的路径)
$uploadFilePath = '/Users/bruce/Downloads/Ts8CYigv.png';
//上传文件名,为什么上传文件名要叫key而不叫filename呢?因为对象存储其实就是一个key value
//的存储结构,你可以认为它就是个redis,key就是redis键名,value就是这个key对应的内容。
$key = basename($uploadFilePath);
//又拍云默认域名在:云存储→选择一个服务并点配置→配置的第一项默认就是域名管理→滚动到最后就能看到默认域名
$defaultDomain = 'http://' . $serviceName . '.test.upcdn.net';

//在对象存储中,其实并没有实际意义上的"目录"(或者叫"文件夹"),整个文件夹和最后的key一起,组成的一个整体也是key
//举例:我要把文件存到"2020/06/02/test.jpg",那么这整个就是一个key,而内容当然就是test.jpg这张图片的二进制数据了。
if($directory){
    //真正使用时,$directory可能是用户传过来的,在不知道用户是否写了右斜杠的情况下,统一先去掉再添加一个
    $key = rtrim($directory, '/') . '/' . $key;
}

//使用又拍云php-sdk上传文件非常方便,很new一个config对象
$serviceConfig = new Config($serviceName, $operator, $password);
// 15728640 = 15M,如果文件大于15M,则使用并行分块上传
if(filesize($uploadFilePath) > 15728640){
    /* uploadType有两个值
       - BLOCK : 串行分块上传
       - BLOCK_PARALLEL : 并行分块上传
    */
    //然后可对new出的config对象的属性继续设置参数(有哪些参数可直接查看Config类: vendor/upyun/sdk/src/Upyun/Config.php)
    //设置uploadType=BLOCK_PARALLEL表示使用并行分片上传
    $serviceConfig->uploadType = 'BLOCK_PARALLEL';
}
$client = new Upyun($serviceConfig);
$fp = fopen($uploadFilePath, 'rb');
$retArr = $client->write($key, $fp);
// var_dump($retArr);exit;

/*
 * 返回的$retArr的值
 * array(6) {
      'x-upyun-content-length' =>
      string(5) "47028"
      'x-upyun-height' =>
      string(3) "473"
      'x-upyun-content-type' =>
      string(9) "image/png"
      'x-upyun-file-type' =>
      string(3) "PNG"
      'x-upyun-width' =>
      string(3) "839"
      'x-upyun-frames' =>
      string(1) "1"
    }
 */

//我们随便拿一个元素来判断是否上传成功
if(isset($retArr['x-upyun-content-length'])){
    //在实际使用中,$key可能是用户传过来的,在不知道$key是否以斜杠开头的情况下,统一先去掉再自己添加一个
    echo $defaultDomain . '/' . ltrim($key);
}else{
    echo 'Upload failed.';
}

好了,到这里就写完了,enjoy!

查看原文

赞 0 收藏 0 评论 0

Willis 回答了问题 · 2019-10-21

解决git add 多个文件,但想忽略某一个文件

先用以下命令添加所有

git add -u

再以下命令排除掉你不想添加进去的某几个文件,比如我这里要排除“static/js/dashboard.js”文件(这个路径可以用git status查看):

git reset -- static/js/dashboard.js

关注 6 回答 5

Willis 回答了问题 · 2019-09-08

php-cli能获取系统剪贴板中的图片吗?

一段时间过去了,也没人知道,我自己研究出来并且还写了个插件:php-get-image-from-clipboard,兼容macOS、Windows、Linux三大平台。

原理:

  • macOS是通过使用php调用pngpaste命令来生成的,需要安装pngpastebrew install pngpaste
  • Windows是通过使用php调用Powershell来生成的,Win10什么都不用动,Win7要升级Powershell到5.1;
  • Linix是通过使用php调试xclip来生成截图的,Ubuntu的话,使用apt install xclip来安装xclip

关注 3 回答 3

Willis 提出了问题 · 2019-06-21

用link标签无法实现http2的server push

服务器已经配置好:

server {
    # listen在原https配置文件基础上添加http2
    listen 443 ssl http2;
    # 添加一句http2_push_preload on表示开启server push功能
    http2_push_preload on;
    ……
}

并且用以下的方式(php)也成功了:

<?php
    header("link: </styles.css>; rel=preload; as=style", false);
    header("link: </script.js>; rel=preload; as=script", false);

但是据说还可以用link标签的方式来指定要推送的资源:

<link rel="preload" href="/styles.css" as="style">
<link rel="preload" href="/script.js" as="script">

但我一直没试成功这种方式,有人知道这是什么问题吗?

关注 2 回答 1

Willis 评论了文章 · 2019-04-26

七牛云图床上传工具-iUploader

软件介绍:
iUploader主要功能将图片上传至七牛云,返回 Markdown 格式的链接到剪贴板

功能介绍:

  1. 图片本地压缩
  2. 图片右键上传
  3. 图片复制上传
  4. 图片拖拽上传
  5. https加密上传

开发:
继承七牛云SDK,使用swift开发,App自签上传凭证,自动选择存储区域,通过https加密上传。


联系方式:

邮箱:iChochy@qq.com
网站:https://iuploader.ichochy.com

注: 处女作
Cloud

查看原文

Willis 评论了文章 · 2019-04-26

分享一个自己写的开源图床ImgURL

ImgURL是一款使用PHP + SQLite 3开发的图床程序,免费开源,支持图像裁剪、压缩、自动鉴黄识别等多种功能,部署简单,管理方便。

目前已经实现的功能

  • 支持拽拖上传、多图上传、Ctrl + V粘贴上传、URL上传
  • 支持图片裁剪,自动生成缩略图
  • 限制访客上传数量
  • 图片压缩/批量压缩
  • 图片鉴黄/批量鉴黄
  • API支持

DEMO

安装ImgURL

其它说明

查看原文

Willis 评论了文章 · 2019-04-26

我的最佳写作方式

最佳喜欢上了写作,喜欢自己写的东西能被别人阅读,赞赏,也希望我写的东西能更有价值,体验也更好。

今天我分享的是我的最佳写作方式。

我的最佳写作方式

工具汇总

markdown编辑器截图工具gif录制工具图床工具
TyporaQQ / wechatlicecapiPic

markdown编辑器 · Typora

完全免费的markdown编辑器,无与伦比的写作体验,让人爱不释手,具体的特性请移步官网:https://typora.io/

我最常用的快捷键是Command+/,可以切换源码模式和打字机模式。

typora

图传工具iPic

仅仅有好的编辑器还不够,还需要图床工具将你的图片自动上传到云端,最好是能够结合你使用的markdown编辑器一起使用,最好是截图后直接粘贴,然后上传。

那么iPic是首选,因为Typora内置了iPic的功能,如下图:

ipic

iPic支持很多种图传工具,我现在用的是腾讯COS,这个工具默认是免费的,但是默认只支持免费的新浪微博图传,如果你要使用其他图传就要收费了,年费50元。

iPic的作者是全职独立开发者Jason,已经写了很多类似的mac工具,都很优秀,官网:https://toolinbox.net/

截图工具

QQ和微信截图应该是大家都在用的,非常方便,截图后可以粘贴到任何地方,QQ还支持视频录制功能。

gif录制工具

这里我就要介绍强大的LICEcap了,用来做屏幕截图的,录制出来的gif很小,我的所有gif都是通过它来制作的。

详细请移步官网:https://www.cockos.com/licecap/

查看原文

Willis 评论了文章 · 2019-04-26

SpringBoot 整合 阿里云OSS 存储服务,快来免费搭建一个自己的图床

Github 地址:https://github.com/Snailclimb/springboot-integration-examples(SpringBoot和其他常用技术的整合,可能是你遇到的讲解最详细的学习案例,力争新手也能看懂并且能够在看完之后独立实践。基于最新的 SpringBoot2.0+,是你学习SpringBoot 的最佳指南。) ,欢迎各位 Star。

笔主很早就开始用阿里云OSS 存储服务当做自己的图床了。如果没有用过阿里云OSS 存储服务或者不是很了解这个东西的可以看看官方文档,我这里就不多做介绍了。阿里云对象存储 OSS文档,:

https://help.aliyun.com/product/31815.html?spm=a2c4g.11186623.6.540.4e401c62EyJK5T

本篇文章会介绍到 SpringBoot 整合阿里云OSS 存储服务实现文件上传下载以及简单的查看。其实今天将的应该算的上是一个简单的小案例了,涉及到的知识点还算是比较多。

一 开发前的准备

1.1 前置知识

具有 Java 基础以及SpringBoot 简单基础知识即可。

1.2 环境参数

  • 开发工具:IDEA
  • 基础工具:Maven+JDK8
  • 所用技术:SpringBoot+阿里云OSS 存储服务 Java 相关API
  • SpringBoot版本:2.1.0

1.3 你能学到什么

  • SpringBoot 整合 阿里云OSS 存储服务并编写相关工具类
  • SpringBoot 整合 thymeleaf 并实现前后端传值
  • SpringBoot 从配置文件读取值并注入到类中
  • 如何自己搭建一个图床使用(通过前端选择图片,支持预览,但不支持修改图片)

1.4 创建工程

创建一个基本的 SpringBoot 项目,我这里就不多说这方面问题了,具体可以参考下面这篇文章:

https://blog.csdn.net/qq_3433...

1.5 项目结构

项目结构

1.6 配置 pom 文件中的相关依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- 阿里云OSS-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

二 配置阿里云 OSS 存储相关属性

我在项目中使用的通过常量类来配置,不过你也可以使用 .properties 配置文件来配置,然后@ConfigurationProperties 注解注入到类中。

2.1 通过常量类配置(本项目使用的方式)

AliyunOSSConfigConstant.java

/**
 * @Auther: SnailClimb
 * @Date: 2018/12/4 15:09
 * @Description: 阿里云OSS存储的相关常量配置.我这里通过常量类来配置的,当然你也可以通过.properties 配置文件来配置,
 * 然后利用 SpringBoot 的@ConfigurationProperties 注解来注入
 */
public class AliyunOSSConfigConstant {
    //私有构造方法 禁止该类初始化
    private AliyunOSSConfigConstant() {
    }

    //仓库名称
    public static final String BUCKE_NAME = "my-blog-to-use";
    //地域节点
    public static final String END_POINT = "oss-cn-beijing.aliyuncs.com";
    //AccessKey ID
    public static final String AccessKey_ID = "你的AccessKeyID";
    //Access Key Secret
    public static final String AccessKey_Secret = "你的AccessKeySecret";
    //仓库中的某个文件夹
    public static final String FILE_HOST = "test";
}

到阿里云 OSS 控制台:https://oss.console.aliyun.com/overview获取上述相关信息:

获取 BUCKE_NAME 和 END_POINT:

获取BUCKE_NAME和END_POINT

获取AccessKey ID和Access Key Secret第一步:

获取AccessKey ID和Access Key Secret第一步

获取AccessKey ID和Access Key Secret第二步:

获取AccessKey ID和Access Key Secret第二步

2.2 通过.properties 配置

#OSS配置
aliyun.oss.bucketname=my-blog-to-use
aliyun.oss.endpoint=oss-cn-beijing.aliyuncs.com
#阿里云主账号AccessKey拥有所有API的访问权限,风险很高。建议创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
aliyun.oss.keyid=你的AccessKeyID
aliyun.oss.keysecret=你的AccessKeySecret
aliyun.oss.filehost=test

然后新建一个类将属性注入:

@Component
@PropertySource(value = "classpath:application-oss.properties")
@ConfigurationProperties(prefix = "aliyun.oss")
/**
 * 阿里云oss的配置类
 */
public class AliyunOSSConfig {
    private String bucketname;
    private String endpoint;
    private String keyid;
    private String keysecret;
    private String filehost;
    ...
    此处省略getter、setter以及 toString方法
}    

三 工具类相关方法编写

该工具类主要提供了三个方法:上传文件 upLoad(File file) 、通过文件名下载文件downloadFile(String objectName, String localFileName) 、列出某个文件夹下的所有文件listFile( )。笔主比较懒,代码可能还比较简陋,各位可以懂懂自己的脑子,参考阿里云官方提供的相关文档来根据自己的需求来优化。Java API文档地址如下:

https://help.aliyun.com/document_detail/32008.html?spm=a2c4g.11186623.6.703.238374b4PsMzWf

/**
 * @Author: SnailClimb
 * @Date: 2018/12/1 16:56
 * @Description: 阿里云OSS服务相关工具类.
 * Java API文档地址:https://help.aliyun.com/document_detail/32008.html?spm=a2c4g.11186623.6.703.238374b4PsMzWf
 */
@Component
public class AliyunOSSUtil {
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AliyunOSSUtil.class);
    private static String FILE_URL;
    private static String bucketName = AliyunOSSConfigConstant.BUCKE_NAME;
    private static String endpoint = AliyunOSSConfigConstant.END_POINT;
    private static String accessKeyId = AliyunOSSConfigConstant.AccessKey_ID;
    private static String accessKeySecret = AliyunOSSConfigConstant.AccessKey_Secret;
    private static String fileHost = AliyunOSSConfigConstant.FILE_HOST;


    /**
     * 上传文件。
     *
     * @param file 需要上传的文件路径
     * @return 如果上传的文件是图片的话,会返回图片的"URL",如果非图片的话会返回"非图片,不可预览。文件路径为:+文件路径"
     */
    public static String upLoad(File file) {
        // 默认值为:true
        boolean isImage = true;
        // 判断所要上传的图片是否是图片,图片可以预览,其他文件不提供通过URL预览
        try {
            Image image = ImageIO.read(file);
            isImage = image == null ? false : true;
        } catch (IOException e) {
            e.printStackTrace();
        }

        logger.info("------OSS文件上传开始--------" + file.getName());

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = format.format(new Date());

        // 判断文件
        if (file == null) {
            return null;
        }
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            // 判断容器是否存在,不存在就创建
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            // 设置文件路径和名称
            String fileUrl = fileHost + "/" + (dateStr + "/" + UUID.randomUUID().toString().replace("-", "") + "-" + file.getName());
            if (isImage) {//如果是图片,则图片的URL为:....
                FILE_URL = "https://" + bucketName + "." + endpoint + "/" + fileUrl;
            } else {
                FILE_URL = "非图片,不可预览。文件路径为:" + fileUrl;
            }

            // 上传文件
            PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, fileUrl, file));
            // 设置权限(公开读)
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            if (result != null) {
                logger.info("------OSS文件上传成功------" + fileUrl);
            }
        } catch (OSSException oe) {
            logger.error(oe.getMessage());
        } catch (ClientException ce) {
            logger.error(ce.getErrorMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return FILE_URL;
    }


    /**
     * 通过文件名下载文件
     *
     * @param objectName    要下载的文件名
     * @param localFileName 本地要创建的文件名
     */
    public static void downloadFile(String objectName, String localFileName) {

        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
        ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFileName));
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 列举 test 文件下所有的文件
     */
    public static void listFile() {
        // 创建OSSClient实例。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 构造ListObjectsRequest请求。
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);

        // 设置prefix参数来获取fun目录下的所有文件。
        listObjectsRequest.setPrefix("test/");
        // 列出文件。
        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
        // 遍历所有文件。
        System.out.println("Objects:");
        for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
            System.out.println(objectSummary.getKey());
        }
        // 遍历所有commonPrefix。
        System.out.println("CommonPrefixes:");
        for (String commonPrefix : listing.getCommonPrefixes()) {
            System.out.println(commonPrefix);
        }
        // 关闭OSSClient。
        ossClient.shutdown();
    }
}

四 Controller 层编写相关测试方法

上传文件 upLoad(File file) 、通过文件名下载文件downloadFile(String objectName, String localFileName) 、列出某个文件夹下的所有文件listFile( ) 这三个方法都在下面有对应的简单测试。另外,还有一个方法 uploadPicture(@RequestParam("file") MultipartFile file, Model model)对应于我们等下要实现的图床功能,该方法从前端接受到图片之后上传到阿里云OSS存储空间并返回上传成功的图片 URL 地址给前端。

注意将下面的相关路径改成自己的,不然会报错!!!

/**
 * @Author: SnailClimb
 * @Date: 2018/12/2 16:56
 * @Description: 阿里云OSS服务Controller
 */
@Controller
@RequestMapping("/oss")
public class AliyunOSSController {

    private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private AliyunOSSUtil aliyunOSSUtil;

    /**
     * 测试上传文件到阿里云OSS存储
     *
     * @return
     */
    @RequestMapping("/testUpload")
    @ResponseBody
    public String testUpload() {
        File file = new File("E:/Picture/test.jpg");
        AliyunOSSUtil aliyunOSSUtil = new AliyunOSSUtil();
        String url = aliyunOSSUtil.upLoad(file);
        System.out.println(url);
        return "success";
    }
    /**
     * 通过文件名下载文件
     */
    @RequestMapping("/testDownload")
    @ResponseBody
    public String testDownload() {
        AliyunOSSUtil aliyunOSSUtil = new AliyunOSSUtil();
        aliyunOSSUtil.downloadFile(
                "test/2018-12-04/e3f892c27f07462a864a43b8187d4562-rawpixel-600782-unsplash.jpg","E:/Picture/e3f892c27f07462a864a43b8187d4562-rawpixel-600782-unsplash.jpg");
        return "success";
    }
    /**
     * 列出某个文件夹下的所有文件
     */
    @RequestMapping("/testListFile")
    @ResponseBody
    public String testListFile() {
        AliyunOSSUtil aliyunOSSUtil = new AliyunOSSUtil();
        aliyunOSSUtil.listFile();
        return "success";
    }

    /**
     * 文件上传(供前端调用)
     */
    @RequestMapping(value = "/uploadFile")
    public String uploadPicture(@RequestParam("file") MultipartFile file, Model model) {
        logger.info("文件上传");
        String filename = file.getOriginalFilename();
        System.out.println(filename);
        try {

            if (file != null) {
                if (!"".equals(filename.trim())) {
                    File newFile = new File(filename);
                    FileOutputStream os = new FileOutputStream(newFile);
                    os.write(file.getBytes());
                    os.close();
                    file.transferTo(newFile);
                    // 上传到OSS
                    String uploadUrl = aliyunOSSUtil.upLoad(newFile);
                    model.addAttribute("url",uploadUrl);
                }

            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "success";
    }
}

五 启动类

@SpringBootApplication
public class SpringbootOssApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootOssApplication.class, args);
    }
}

六 上传图片相关前端页面

注意引入jquery ,避免前端出错。

index.html

JS 的内容主要是让我们上传的图片可以预览,就像我们在网站更换头像的时候一样。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>基于阿里云OSS存储的图床</title>
    <script th:data-original="@{/js/jquery-3.3.1.js}"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #submit {
            margin-left: 15px;
        }

        .preview_box img {
            width: 200px;
        }
    </style>
</head>
<body>

<form action="/oss/uploadFile" enctype="multipart/form-data" method="post">
    <div class="form-group" id="group">
        <input type="file" id="img_input" name="file" accept="image/*">
        <label for="img_input" ></label>
    </div>
    <button type="submit" id="submit">上传</button>
    <!--预览图片-->
    <div class="preview_box"></div>
</form>
<script type="text/javascript">

    $("#img_input").on("change", function (e) {
        var file = e.target.files[0]; //获取图片资源
        // 只选择图片文件
        if (!file.type.match('image.*')) {
            return false;
        }
        var reader = new FileReader();
        reader.readAsDataURL(file); // 读取文件
        // 渲染文件
        reader.onload = function (arg) {

            var img = '<img class="preview" data-original="' + arg.target.result + '" alt="preview"/>';
            $(".preview_box").empty().append(img);
        }
    });
</script>
</body>
</html>

success.html

通过 <span th:text="${url}"></span> 引用后端传过来的值。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>上传结果</title>
</head>
<body>
<h1>上传成功!</h1>
图片地址为:<span th:text="${url}"></span>
</body>
</html>

七 测试我们的图床

访问 :http://localhost:8080/

① 上传图片

② 图片上传成功返回图片地址

③ 通过图片 URL 访问图片

通过图片 URL 访问图片

我们终于能够独立利用阿里云 OSS 完成一个自己的图床服务,但是其实如果你想用阿里云OSS当做图床可以直接使用极简图床:http://jiantuku.com 上传图片,比较方便!大家可能心里在想那你特么让我实现个图床干嘛?我觉得通过学习,大家以后可以做很多事情,比如 利用阿里云OSS 存储服务存放自己网站的相关图片。

ThoughtWorks准入职Java工程师。专注Java知识分享!开源 Java 学习指南——JavaGuide(12k+ Star)的作者。公众号多篇文章被各大技术社区转载。公众号后台回复关键字“1”可以领取一份我精选的Java资源哦!

我的公众号

查看原文

Willis 提出了问题 · 2019-04-26

php-cli能获取系统剪贴板中的图片吗?

像Python就可以通过用Pillow(PIL)来获取剪贴板中的图片,php脚本纯获取吗?我知道用javascript可以,但我现在要做的不是通过Web,而是直接用php脚本本身去获取。

剪贴板中的图片:意思是截图后复制到剪贴板,又或者是从网页中右击图片→复制图片(注意不是复制图片链接,是复制图片)这样复制到剪贴板中的:
clipboard.png]

如果使用系统的剪贴板函数是不行的,比如Mac的pbpaste,win的clip,Linux的xsel都只能处理剪贴板中的内容为纯文本的情况,如果是图片,它们获取不到任何内容。

google了好久也没查出来,所以想来问问大家。

关注 3 回答 3

Willis 评论了文章 · 2019-04-23

markdown博客图床上传的艰辛之路

markdown用着很爽吧,但是图片存哪呢? 写给所有写静态博客,又想搞个图床的人。

1. 适用场景

假如你用github page用markdown写个人博客的话,而你正好又用到一些图床的话,那你可以继续看下去。

2. 图床分类

图床可以分为两类:

  1. 付费类:云服务提供的对象存储: 例如七牛、阿里云提供的对象存储
  2. 免费类:专门的图床网站: 例如sm.ms, 路过图床,极简图床类似的,一般都是免费。优点是免费,缺点图片丢了就丢了,网站挂了就挂了,毕竟人家又没收你的钱

先说云服务提供的对象存储。

2.1. 七牛云

七牛图床也是推荐比较多的。而且七牛OSS在认证过后提供免费的10G存储空间,你看到的是免费10G存储空间

但是还有些信息没有告诉你。

  1. 免费的仅仅是存储空间,流量费超标了,还是要另算费用的哟
  2. 免费提供的外链仅仅是HTTP, HTTPS可是不免费的哟
  3. 免费提供的图片的外链是测试的域名,30天后会被回收的哟。也就是说,如果你用测试域名,那么你的图片很可能不知哪天就无法访问了。当然了,你也可以绑定一个正式的域名,但是你需要买个域名,对这个域名进行域名备案、公安网备案。如果你仅仅是为github pages搞个图床,那备案之路是不容易的就好比你想吃个茶叶蛋,但是小卖部老板要求你要写出一篇不少于800字的文章,从鸡蛋的外壳上去证明这只母鸡产下这枚蛋的心情。你要考虑是否值得。

2.2. 阿里云

如果你用阿里云的对象存储,阿里云是没有免空间的,但是其实空间并不贵,我之前买的9块钱40G一年的空间。而且阿里云提供正式的外链域名,域名是不会被回收的。

但是如果你以为阿里云很划算的话,你就很傻很天真了。

阿里云的对象存储计费是慢复杂的,而且不便宜。

阿里云OSS计费由四个部分组成: 存储费用 + 流量费用 + 请求费用 + 数据处理费用

至于具体计费细节我就不多说了,只说一个真实的故事。

七牛云给出测试域名回收通告之后,当天我就把500多张图片,大概24MB左右,全部迁移到阿里云OSS。当晚凌晨左右,正在躺在床上看灌篮高手的正起劲的我,突然收到阿里云OSS欠费通知。于是我虎躯一震,翻身下床,打开电脑,还了欠费,删了OSS。

总之,天下没有免费的午餐,出来混,总是要还的。

2.3. 又拍云

又拍云提供的外链,也是需要绑定域名的,而且域名需要备案。

2.4. 专门的图床网站

专门的图床网站,一般都是免费的。但是免费的,除非站长能力超强、票子超多,否则没有盈利模式的话,早晚可能还是免不了无法访问的结局。

详情可以看一下, 盘点一下免费好用的图床

3. 为了方便、还是为了折腾

给markdown图片一个图床,出发点是为了方便。为了markdown在迁移时,图片不会无法访问。

但是我觉得在这个出发点上,我越绕越远。为了方便,而折腾出一系列麻烦事。

4. 解决思路

  1. 博客尽量少加图片
  2. 尽量将图片放在博客目录下,不使用图床
  3. 对于不重要的图片,可以使用免费图床
  4. 可以购买一些付费的专门的图床服务
  5. 或者干脆使用github issue写博客,它是支持图片上传的
  6. 或者就sf,或者一些博客平台写博客
  7. 各种支持将图片上传到各个图床的工具也层出不穷,小心着用

5. 结论

  • 天下没有免费的午餐,我妈妈曾经在平多多上买了几分钱的床单,收货后觉得连尿布都不如。(我是笑着劝她不要买😁)
  • 出来混,最后总要还的
  • 如无必要,勿增实体。不要为了简单,反而让事情变得更复杂。奥卡姆剃刀原理
查看原文

Willis 回答了问题 · 2019-04-22

上传图片到sm.ms疑似被封ip

没人回答自己回答吧,因为过了段时间我觉得我大概知道原因了,因为它服务器在国外,只要是在国外的服务器,由于众所周知的原因,都有可能出现这个问题,自己加个代理选项就好了,以下是示例代码

$GuzzleConfig = [
    'base_uri' => $this->baseUri,
    'timeout'  => 10.0,
];
if($this->proxy){
    $GuzzleConfig['proxy'] = $this->proxy;
}
//实例化GuzzleHttp
$client = new Client($GuzzleConfig);
//upload?ssl=1
//post file to https://sm.ms
$response = $client->request('POST', 'upload?ssl=1', [
    'multipart' => [
        [
            'name'     => 'smfile',
            'contents' => fopen($uploadFilePath, 'r')
        ],
    ]
]);

$string = $response->getBody()->getContents();

$this->proxy的值是127.0.0.1:1086这样的,1086是本地的http代理端口(你的科学上网工具如ss的http端口)

关注 1 回答 1

Willis 提出了问题 · 2019-04-22

python3怎样获取从资源管理器(Win)/访达(Mac)中复制的文件的绝对路径?

python现有的获取剪切板内容的功能比如pyperclip.paste(),只能获取文本,如果复制文件的话,它获取到的只是文件名,不是绝对路,并且复制多个文件只会获取到最后一个文件的文件名,而ImageGrab.grabclipboard()这个是PIL库的,可以获取剪切板的截图并把它存为图片,但如果我直接右击文件→复制,或选中文件→ctrl+c这样复制图片文件本身的话,它就无法获取了,我目前看到有人说可以用PyQt5来获取,不过我做的是脚本工具,那个PtQt5弄的好像会出来一个python程序图标而且我也不知道怎么用,请问有人知道怎么获取剪切板中的文件路径吗?有没有哪个包可以兼容Mac/Win/Linux?或者分开处理的话也行呀。

关注 1 回答 0

Willis 回答了问题 · 2019-04-13

py2app打包程序报错

我也是遇到这个问题,楼主解决没?

关注 7 回答 6

Willis 发布了文章 · 2019-03-27

一个还不错的图床工具-PicUploader

PicUploader

PicUploader-logo.png

PicUploader 是一个用php编写的图床工具,它能帮助你快速上传你的图片到云图床,并自动返回Markdown格式链接到剪贴板。配置完成后,要获取一个可用于markdown的图片外链只需要:

  • 方式一: 右击电脑本地图片→点击你的自定义上传菜单→系统通知图片上传成功→到Markdown编辑器中粘贴!
  • 方式二: 截图并点击复制到剪贴板→按快捷键→系统通知图片上传成功→到Markdown编辑器中粘贴!
  • 方式三: 右击网页中的图片→点击复制图片→按上传快捷键→系统弹出上传成功通知→到Markdown编辑器中粘贴!
  • 方式四: 使用网页版上传,包括拖放上传(支持多文件)、复制本地图片文件后粘贴上传、截图后粘贴上传、复制网页上的图片后粘贴上传、点击上传按钮选择图片后上传(支持多文件)。

主要功能

  • 支持Mac和Windows(也可用于Linux服务器端)、理论上也支持Linux桌面版,只要你能添加右键菜单或者用快捷键调用上传命令的话;
  • 支持图片压缩后上传(支持jpg/png/webp,gif/bmp不支持压缩);
  • 支持添加水印后上传(支持文字水印、图片水印、自定义水印颜色/透明度/角度/位置,支持jpg/png/bmp/webp,gif不支持水印);
  • 返回的链接可自定义(如原始链接、Markdown格式链接、可点击的Markdown格式链接、完全自定义的链接);
  • 完全自定义上传文件名(可选变量有当前年、月、日、当前时间戳,随机字符串(可调长度))
  • 可作为MWeb的API使用,可作为PicGo、ShareX、uPic等的自定义图床使用;
  • 支持快捷键上传剪贴板中的图片(配合PicUploaderHelper/Alfred/WinHotKey使用);
  • 支持Web端拖放、粘贴、或直接选择上传图片;
  • 支持Web端设置所有参数;
  • 支持上传任意格式文件(不只是图片);
  • 目前支持的图床:七牛、阿里、腾讯、华为、网易、京东、百度、又拍、青云、Ucloud、sm.ms、Imgur、Github、Gitee(码云)、微博、Nextcloud、Cloudinary、Chevereto、Aws s3、金山、个人服务器(sftp)、本地(即PicUploader所在机器)。

功能演示

如果图片看不了请点击图片上边的文字链接单独打开即可查看。


Mac右击图片上传演示(图片不动请点我查看)
Mac-demo.gif

Mac快捷键上传截图演示(图片不动请点我查看)
Mac-shortcut-upload-demo.gif

Win10右击图片上传演示(图片不动请点我查看)
Win10-upload by right click

Win10快捷键上传截图演示(图片不动请点我查看)
Win10-upload by shortcut

Win7右击图片上传演示(图片不动请点我查看)
demo-win7.gif

Win7快捷键上传截图演示(图片不动请点我查看)
Win7-upload by shortcut

Web版演示
screenshot_upload_tmp.jpeg

上传任意格式文件演示(图片不动请点我查看)
upload-non-image-demo_optimized.gif

MWeb使用PicUploader上传图片演示
screenshot.jpeg

ShareX使用演示(图片不动请点我查看)
sharex-customize-upload-demo_optimized_optimized.gif

上传记录
Xnip2019-05-01_00-50-56.jpg

由于维护多个文档太累,Github flavor markdown不支持视频,并且gif图大点就不显示,还得空两格才会换行,基于种种原因,如果要继续查看文档,请直接查看唯一文档:PicUploader: 一个还不错的图床工具

查看原文

赞 1 收藏 1 评论 0

Willis 评论了文章 · 2019-03-25

Mac版:上传图片到远程图床哪家强?

markdown写文档虽然如行云流水,但是一旦需要引入图片了。往往需要四五步操作,如果图片仅仅保存在本地,那么复制markdown时,图片路径往往都不对了,还要重新上传一遍图片,很是麻烦。

因此,最好把图片直接上传到图床上,然后通过公网链接来引入图片。图床选择上,我选择七牛云。

我在网上找到了3个不错的工具,在此记录一下。

1 三个工具分析一览

这些工具在上传图片成功后,会把链接保存在剪贴板中,在markdown文件中只需要粘贴一下就可以了。

名称收费标准优点缺点推荐指数说明下载地址
ipic50元/年支持很多的云服务,压缩,拖拽上传死贵, 免费版只能用新浪图床,图片很可能会丢失A功能很多,价钱死贵可通过mac app store 下载
UCQCloud免费免费,支持压缩,拖拽上传,截图上传仅支持七牛,服务器仅支持华东和华北AAA免费,功能够用UCQCloud1.3.3.dmg
cuImage终身1元剪贴板上传,压缩上传,拖拽上传,快捷键上传,自动把链接转成markdown的形式仅支持七牛AAAAcuImage的压缩率要比UCQCloud高很多可通过mac app store 下载

总体来说:如果你用七牛图床,cuImage是性价比最高, 用户体验最好的

2 三个工具操作截图与简介

2.1 cuImage

  • 图片上传完成后自动复制URL。
  • 在“上传历史”中查看已上传图片。
  • 批量上传图片。
  • 通过截图或复制上传图片。
  • 通过拖拽上传图片。
  • 通过”服务“菜单上传图片。
  • 通过全局快捷键上传图片。
  • 上传之前压缩图片。
  • 支持BMP/JPEG/PNG/GIF/TIFF等多种文件格式。
  • 只支持七牛云,已兼容七牛云华东、华北、华南及北美的存储区域。

2.2 UCQCloud

1、文件上传(带上传进度)

  • 支持软件面板拖放、选择文件(任意二进制文件)上传
  • 支持状态栏粘贴板图片上传
  • 支持状态栏拖放文件上传

2、图片高质量压缩

  • 本地图片上传使用Tinypng在线高质量无损压缩
  • 粘贴板图片上传使用开源库pngquant压缩
  • 正常情况压缩节省50%以上空间,大幅提高博客图片加载速度,节约网盘存储空间。

3、上传历史记录管理

  • 文件预览查看,删除,拷贝上传外链地址等

4、支持文件夹批量处理

  • 直接拖入文件夹,或文件批量处理

作者:huluo666
链接:https://www.jianshu.com/p/694...
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


2.3 ipic

图床神器 iPic 可自动上传图片、保存 Markdown 链接,给你前所未有的插图体验。

  • 上传前压缩图片
  • 通过拖拽上传图片
  • 通过服务上传图片 [Command + U…

3 参考文献

查看原文

Willis 发布了文章 · 2019-02-23

Mac实用技巧之:访达/Finder

更多Mac实用技巧系列文章请访问我的博客:Mac实用技巧系列文章

Finder就相当于windows XP系统的『我的电脑』或win7/win10系统里的『计算机』(打开后叫资源管理器),find是查找的意思,那Finder就是查找者,寻找者,或者说是查找器,是用来管理你系统各种软件、程序,文档,图片视频等资源的管理器,所以说windows叫资源管理器是很合理的,Finder以前不翻译,直接就叫Finder(中文版也没有翻译),后来可能想讨好更多的中国人,翻译成:访达,既是音译,又是意译,意为访问,达到的意思,从翻译角度来说,真是妙极了,可是不知道是习惯了windows叫资源管理器还是习惯了Mac以前直接叫Finder,突然叫访达,总感觉怪怪的!诸如此类的翻译还有:程序坞(Dock)、启动台(Launchpad)、隔空投送(AirDrop)、调度中心(Mission Control)、聚焦(spotlight),更搞笑的是,谷歌浏览器windows版,窗口就叫窗口,Mac版竟然翻译成:电动窗,没错,就是叫『电动窗』,感觉是刚学汉语的歪果仁翻译的。

1. Finder显示当前文件路径

image.png

2. Finder显示隐藏文件快捷键

以前想在苹果电脑上查看隐藏文件,还得用终端命令。升级到 macOS Sierra 以上的系统后,按 command + shift + .就能直接在 Finder 里显示隐藏文件(看好了最后那个是英文句点『.』),再次按就是隐藏回去。
另外一种方法是,用命令直接打开隐藏文件夹(不需要用上面的命令先切换成显示隐藏文件)

open ~/.ssh

执行这个命令就能直接在Finder中打开~/.ssh这个隐藏文件夹

3.Finder同时查看多个文件或文件夹总大小

选中多个文件或文件夹后,按option+command+i,或者右键弹出菜单之后,按住option键,菜单的显示简介会变成显示检查器,点击显示检查器,即可查看所有选中的文件的总大小(注意,如果选中多个文件后,按command+i,即没有按option,或者直接点击右键菜单的显示简介,则会每一个文件都弹出来一个属性窗口,如果你全选的文件上百个,那它就会弹出来上百个属性窗口,所以一定要注意,否则弹出几百个属性窗口也是挺恐怖的)
同时查看多个文件总大小.gif

4. 查看整个目录的大小

当在目录外面时,直接右键点击Get Info就行(中文:显示简介),如果在目录里面,则在空白处右键Get Info就行,不需要全选再右击再按着Option键查看Get Info(虽然这样也可以,实际上这样看会小一点点,因为没有加上文件夹本身的大小,文件夹总大小=文件夹里所有文件总大小+文件夹本身的大小)
ScreenFlow.gif

5. 复制Finder中某个文件的路径

Finder的文件路径在Finder的下部,而且无法像windows那样在地址栏可以复制路径,但还是有方法。

1)方法一:右键+option

先选中文件,可以是一个或多个文件,如果是一个文件直接右击就行,不需要先选中,然后右击→注意看拷贝按钮→按住option键→拷贝按钮是不是变成拷贝路径了?对,现在点这个按钮就可以拷贝路径了,多个文件的路径是换行符隔开。
<p align="center"><img data-original="https://img.xiebruce.top/2018...; title="ScreenFlow.gif" alt="ScreenFlow.gif"></p>

2)方法二:自己制作一个复制路径的右键菜单

我们可以使用Automator(自动操作)制作一个服务(制作后就会出来一个右键菜单),这样复制路径就非常方便,比windows方便多了!

Automator就是下图这玩意,中文叫自动操作,它在启动台实用工具里面。
Xnip2018-11-16_10-21-38.jpg

打开Automator,点击左下角的新建,如下图,搜索copy,把搜索出来的“Copy to Clipboard”拖动到右侧,并把右侧上边的Service receives selected 后边选择“files and folders”,in后边选择“Finder.app”,最后command+s保存,命令为:Copy path即可(你也可以用中文:复制路径),以后右键菜单就会出现这个按钮。
image2.png

右键制作完成后,使用效果如下:
ScreenFlow3.gif

3)使用终端

打开终端,把要复制路径的文件拖动到终端就可以看到路径,然后复制!
ScreenFlow6.gif

6.在Finder中前进和后退

command+[command+ ]:即command+中括号的两边,这个是历史的前进与返回,建议自己从进几层目录然后用这两个快捷键试一试就清楚。
command+↑command+↓:这个跟上边不一样的是,command+↓需要你选中某个目录后才能操作,这个快捷键相当于鼠标双击(没错,它不仅可用于打开文件夹,还可用于打开程序,所以说它相当于鼠标双击),而command+↑是一个与command+↓相反的动作,只有先按了command+↓,才能用command+↑返回。

7. Finder中按shift无法连续选文件的解决方法

我们知道,在windows系统下,先选中一个文件,然后按住shift,再点击另一个文件,那么这两个文件之间的文件都会被选中,然而在mac的Finder中只有使用列表显示方式才可以,如果使用缩略图显示方式,则不行。

如下图,第一次点击第二个文件的时候,其实我是按了shift键的,但是却不能连续选中中间的文件,而第二次我用列表显示方式,选中一个文件后,按着shift键再点另一个文件,就连续选择了,当然mac也可以像windows那样用鼠标拖选。
ScreenFlow7.gif

如果用键盘的话,在缩略图模式也是可以多选的,方法是按Shift+↓,每按一次↓,都会选中一行(如果第一个没有默认被选中,则第一次会选中第一个),如果只是选中其中一个,在已选中其中一个的情况下,用上下左右方向键就可以。
ScreenFlow9.gif

8. Finder快速定位到顶部和底部

在Finder里,当文件很多时,我们有时候希望能用快捷键快速到达顶部或者底部,当然用鼠标滚动也可以,但是对于快捷键党来说,鼠标滚动简直太慢了有木有,快捷键方法是在「列表」显示模式下,按option+↑option+↓,如果在缩略图模式下按这两个快捷键,跟直接按方向键是一样的。
ScreenFlow10.gif

9. Finder用所选项目新建文件夹

如下图所示,右键菜单里的英文对应的中文就叫用所选项目新建文件夹,这个比windows强大吧,windows可没这功能,另外第二次我是用快捷键的control+command+N(N:new)。
ScreenFlow11.gif

10. Mac的复制、剪切和粘贴快捷键是什么?

  • 在Mac中,把command键当成windows的ctrl键使就行了,所以聪明的你肯定想到,那Mac的复制粘贴快捷键就是command+C,command+V了,没错,就是酱紫!
  • 那剪切呢?也像windows那样用command+X吗?呃,对于编辑器里的文本来说,确实可以这样,command+X就是剪切,command+V就是粘贴,但是对于文件和文件夹,没有这个功能,因为在Mac中,执行剪切后文件会「不见了」,就像你在编辑器里剪切文本那样,文件被剪切后就放到剪贴板中了(而不像windows是变成灰色),万一你忘了粘贴,那文件就相当于被『删除了』,所以Mac没提供剪切这个功能。
  • 那Mac是不是就不能实现『剪切』这个功能了呢?显然不是,Mac有一个跟剪切类似的操作,但它不叫剪切,它叫『移动』,只要你在粘贴时,多按一个option键(即command+V变成option+command+V),那么文件在粘贴时,就会被移动过去(而不是复制一份),这样就相当于windows的『剪切』后再粘贴了。当然,如果你用鼠标粘贴,那你可以先右击鼠标出来菜单之后,按住option键,然后『粘贴』按钮就会变成『移动』按钮了。
  • 有些人可能会觉得奇怪,Mac为什么没有剪切?而是用移动代替?如果你懂Linux,你会觉是Mac的这个操作,很正常,因为在Linux里,也没有所谓的『剪切』,只有复制和移动(复制就是cp,移动就是mv),因为Linux属于类Unix,而macOS基于Unix内核,它们的运行机制都是一样的,相反,Windows的『剪切』操作才奇怪,世界上这么多系统,也就只有windows才有『剪切』这种操作(当然可能有一些基于Linux的系统会模仿Windows)。
  • 鼠标复制粘贴,快捷键一样效果,自己试试就行

ScreenFlow12.gif

  • 鼠标复制移动(注意右键菜单出来后,按下option键,粘贴才会变成移动),可以看到移动后,左边的不见了,移到了右边,这就相当于windows的剪切——粘贴功能。

ScreenFlow13.gif

11. Mac右键菜单的『复制』和『拷贝』

  • 绝大部分Mac用户都是从windows过来的,大家在windows可能复制粘贴都玩的很溜,但是到了Mac,却发现有点奇怪,刚开始可能不注意,想把一个文件复制到另一个地方,直接右击→复制,结果却发现这个文件又多了一份,假如被复制的文件名为『风景.png』,则莫名奇妙多出来的那个文件名可能叫『风景 copy.png』或者中文『风景 的副本.png』,有人觉得奇怪,为什么我复制一个文件还没粘贴呢,就自动出来一份呢?后来他可能发现,原来对『风景.png』右击,出来的菜单不止有『复制』按钮,还有『拷贝 风景』这个按钮,哦,这样发现,要复制粘贴一个文件,应该点『拷贝 xxx』而不是点『复制』,而『复制』这个按钮,因为前面已经试过了,就是把原文件直接复制出一个副本,感觉上好像没啥用,因为复制一般都是复制到别的地方,在同一个目录整两份一模一样的干嘛?可能只是你暂时用不到,其实有时候用到的时候还是挺方便的,比如我一个文档要修改第二版,我就直接command+D就复制了一份了,而windows要完成同样的功能,要先ctrl+Cctrl+V
  • 其实复制和拷贝,用英文duplicate(复制)和copy(拷贝)这样就明白的多,duplicate(复制)的快捷键是command+D,D就是duplicate的首字母,也就是说我们要快速把一个文件复制多个副本,只在不断按command+D即可,而拷贝则是我们平时所说的『复制』,其实我认为,duplicate不应该翻译为『复制』,而应该翻译成『制作副本』或『生成副本』或『拷贝副本』这样会容易理解一点。
  • 还有另一点就是,Mac的拷贝总是会带上后面的文件名,所以你会发现每次想拷贝的时候都找不到拷贝按钮,因为每次名字的长短都不一样(看被拷贝的文件名的长短)
  • Mac中复制和拷贝的区别(第二步点击拷贝后,我没有粘贴,所以没有反应是正常的)

ScreenFlow14.gif

  • 复制(Duplicate)还可以用鼠标,Finder在列表模式或缩略图模式下,先按住option键,再用鼠标拖动文件,就会出来一个『+』号,然后放开文件,就会复制(Duplicate)一份副本了;另外先鼠标拖动文件不要放开鼠标,再按option键,效果一样,也会出来一个『+』号,放开鼠标即可制作一份副本。

tips:其实用过photoshop的童鞋,肯定知道photoshop也可以这样复制图层(photoshop也是先按option键,再拖动图层来复制这个图层的)
ScreenFlow3.gif

  • 当我们command+C复制了某个文件,想用快捷键command+v把文件粘贴到当前鼠标选中的文件夹中,是不行的(这点跟win一样),但用鼠标右击该文件夹再点击菜单中的粘贴,是可以粘贴到被选中的文件夹里面的。

ScreenFlow6.gif
macOS比Windows高级的地方是,它的列表可以显示成树状(windows是在侧边栏显示树状,用起来不那么方便),在树状视图中,你可以把文件粘贴到鼠标选中的子菜单中
ScreenFlow5.gif

12. Mac同时修改多个文件名或扩展名

  • Mac可以同时修改多个文件的文件名(包括扩展名),下图为同时修改文件名,把图片按顺序命名,windows没这功能吧?

ScreenFlow15.gif

  • 修改文件名很正常,默认修改扩展名是会弹出提示的,比如我有一次要给2000多个图片添加扩展名,结果它一个一个弹出来问我是否要修改扩展名,如果不关闭这个选项,那么我就要确认2000多次,关键是默认是“否”(所以不能一直按回车确认)设置方法是:FinderPreferencesAdvanced,去掉『更改扩展名之前显示警告』前面的勾即可。可以看到,我将jpeg修改为png的时候,每个都弹提示,很烦,每后来去掉提示之后,再从png修改回jpeg就不弹了,有人可能会说jpeg直接修改成png,这样是不对的,但这只是个例子,有时候会遇到类似这种情况的,其实并不一定是修改格式(有可能文件名本身已经有一个点,再修改的时候它就认为我们在改扩展名,其实不是的)

ScreenFlow16.gif

13. Finder搜索技巧:NOT *

『NOT *』可以把子目录及文件跟最外层目录同级显示,『NOT * 』的含义是所有名称中不含星号的文件或文件夹,而一般文件名或文件夹名不可能出现『*』号,所以全部文件都被搜索出来了。

未展开
image5.png

已展开
image4.png

搜索框输入『NOT *』后,所有内部文件全部同级显示
image3.png

14.Finder在当前目录新建一个文件

  • 众所周知,Mac是无法右击鼠标在当前目录新建文件的(只能新建文件夹),你要新建什么文件,就得打开对应的软件,然后保存文件到前面所说的“当前目录”,比如我要新建一个文本文件,我也得打开textEdit(即『文本编辑』),然后往前面所说的“当前目录”里面保存,如果这个“当前目录”藏的很深,那么会很麻烦,要一级一级往下选好多次,简单的办法是保存到先“下载”里面,然后Finder新开一个tab,复制刚才保存到“下载”里的文件,然后Finder切换前面所说的“当前目录”那个tab,然后再粘贴或者移动到这里!
  • 而我觉得,其他格式的文件不能直接创建就算了,连普通文本文件也不能在当前目录创建,就有点说不过去了,为此,我们可以通过安装NewFileMenu(收费,可以去waitsun搜索下载大众授权版)这个软件来解决!这款软件可以让你自己勾选哪些软件要出现在新建文件菜单中,非常方便!
  • 安装『NewFileMenu』这个软件后的新建文件菜单

image6.png

15. 在Finder显示资源库(~/Library)

1)使用命令

  • 显示:chflags nohidden ~/Library(显示后如果不执行隐藏命令,则一直都是显示,本质上是把Library变成非隐藏状态)
  • 隐藏: fchflags hidden ~/Library

2)使用快捷键『shift+command+. 』

  • 不止Library,其他隐藏文件也会显示出来(本质是把Finder设置成显示隐藏文件,Library本身还是隐藏状态)

3)使用Finder菜单栏的『前往』按钮

  • 鼠标点击Finder顶部菜单中的『前往』(英文『go』),然后按住神奇的option键,Library便显示出来了。

ScreenFlow17.gif

4)不显示,直接进入

  • 直接『shift+command+g』输入『~/Library』回车进入到『~/Library』目录里(注意:这里可以使用tab键补全)。

5)使用open命令

  • 在终端输入open ~/Library,回车,即可自动在Finder/访达中打开Library目录。

16. 修改Finder菜单顺序

按住 Command 再拖动鼠标可以改变Finder菜单图标的顺序
ScreenFlow18.gif

17. Finder前往文件夹和连接服务器

1)前往文件夹

  • 快捷键:shift+command+g(g: go)

2)连接服务器

  • 快捷键:command+k,连接服务器一般是连接共享服务器,比如内网共享文件用的ftp服务器或者samba服务器,有些用户或能不知道什么是samba服务器,但是可能使用过,比如在公司有共享文件的地址,一般在windows地址栏输入:\\192.168.xx.xx这样就能进入,但是在Mac上,并不是这样,在Mac上要进入这种共享,要输入:smb://192.168.xx.xx 这样的地址,因为这种共享其实就是samba共享,它的协议就是smb协议。
  • 下图是前往文件夹和连接服务器的鼠标操作方式

ScreenFlow19.gif

18. Finder建立文件夹的快速入口

  • 像windows的资源管理器一样,Mac的Finder一样可以把你要快速进入的文件夹拖到左侧的,这样要进这个文件夹,直接点一下就进去了(即使实际上这个文件夹的目录很深)

ScreenFlow20.gif

19. Finder强大的标签功能

  • Finder左侧默认有很多颜色标签,对文件进行加标签可以对文件进行分类,标签与目录不同的是,一个文件可以属于多个标签,即可以交叉,而且标签还可以自己创建,而且标签名称支持emoji表情,也就是说你可以把标签加个logo,比如『待办事项』你可以加个日历logo
  • 添加标签(忘了一个文件同时加多个标签了,你们自己试就可以)

ScreenFlow21.gif

  • 给标签加emoji表情图标(emoji快捷键:control+command+空格)

ScreenFlow22.gif

20. Finder强大的查询功能

  • 在Finder里点击右上角的搜索框随便输出字符(或者快捷键『command+F』)即进入搜索模式(『option+command+空格』也可以直接新开一个搜索,不过直接新开的是直接搜索整个电脑的,而按command+F或鼠标点击搜索框进入的搜索默认也是搜索整个电脑,但Finder偏好设置可以设置为搜索当前目录的)
  • 如下图,右边有加号和减号,可以添加组和条件搜索,按类型,按文件扩展名等各种搜索

  • 搜索条件默认不显示,只有你输入搜索关键字后,才会显示出来,比如,我就想按日期搜索(不想用关键字),这时,你可以随便输入一个搜索关键字(比如我一般输入数字1),等搜索条件出来后,再选择搜索条件,最后再把这个1去掉即可(当然你也可以用option+command+空格直接呼出条件搜索界面,但是这样会新打开一个Finder/访达窗口)。

21. Finder下方的路径可接受拖拽

  • 每一级都能接收拖拽的,如下图,我把当前目录的NewFile.txt拖到它的上级目录,而且这些目录也可以右击出来菜单进而进行操作的

1039366.png

22.保存文件时用快捷键快速定位到某个目录

  • 如『桌面』是shift+command+D,『下载目录』是option+command+L,『我的文档』目录是shift+command+O

ScreenFlow23.gif

  • 其实这些快捷键就在Finder的『前往』菜单栏中能找到

80426545.png

23. Finder的几种预览模式

  • 我个人最喜欢列表模式,因为文件名能看全,最后一种是看图用的,Mac最装逼的模式🤣

ScreenFlow2.gif
注:自MacOS 10.14(即Mojave)起,Cover flow浏览模式被移除,换成了gallery(画廊)模式,这种模式主要好处就是右侧能看到图片的详细信息,so,以后没法装逼了:
Xnip2018-09-25_11-54-05.png

24. 重启Finder的两种方法

有时候由于各种原因,Finder可能会卡住,这时如果你的鼠标还能动,那么你可以试试重启Finder。

1)按住option键右击Finder

按住option键不放,然后鼠标右击程序坞左下角的Finder,弹出来的菜单最后一项就是重启(此时放开option键,重启菜单也不会消失),单击即可重启。注意是先按住option再右击Finder,如果先右击再按住option,那最后一个菜单会由隐藏(Hide)变为隐藏其他(Hide Others)

  • 未按住option右击Finder

Xnip2018-09-25_02-03-27.png

  • 按住option右击Finder

Xnip2018-09-25_02-03-52.png

2)在『强制退出应用程序』中重启

我们知道,使用快捷键option+command+esc可以调出『强制退出应用程序』窗口,在里面,选中一个你要退出的程序,点击右下角的强制退出按钮即可强制退出程序。但如果你选中的是Finder,那么右下角的菜单则不是强制退出,而是重启(Relaunch),点击它即可重启Finder。
Xnip2018-09-25_02-11-53.png

25、重命名一个文件

  • 可以像Windows一样,鼠标选中文件后再点一下即可重命名。
  • 选中文件后按一下回车键即可重命名(Windows按回车键是进入目录/启动程序,在Mac中这个操作可以用command+O或command+↓来实现)
查看原文

赞 0 收藏 0 评论 0

Willis 评论了文章 · 2019-02-22

gitPic,利用Github做图床小工具

前言

最近使用自己搭建的一个博客系统Fame写博客,博客中的图片是利用github做图床的,配合RawGit获取图片中的链接,只是这样每次都感觉很麻烦,于是写了一个小工具方便上传图片和获取链接。

环境需求

  • java8+(如果没有java环境也提供带jre版本的,只是体积就emmmm.......)
  • git

快速使用

  1. 首先要有一个github账号,然后创建一个respository。

    Step1

  2. 给这个respository起一个名字,我们这里取名为git_resource。然后可以在Desciption中填写一些介绍。接下来勾选Initialize this repository with a README。最后点击Create repository

    Step2

  3. clone项目到本地。注意选择是https方式还是ssh方式,如果已经配置好ssh方式的话建议用这种方式,因为https需要输入账号密码。

    Step3

  4. 打开gitPic软件,有java环境就在jar包目录下执行命令java -jar gitPic-java.jar,没有java环境就解压gitPic-exe.rar点击exe文件。
  5. 在gitPic中选择你要作为图床的git项目,在本案例中就是刚才创建的git_resource(选择后会读取该项目下的git信息,获取会花一点时间),然后再选择要保存图片的文件夹,比如你的java系列的图片可以放在git_resource项目下的java文件夹下。

    Step4

  6. 拖拽图片或者点击选择图片来选择要上传的图片,gitPic会自动将该图片复制到git_resource/java文件夹下,并且生成对应的图片链接,而且该链接已经复制到你的剪贴版中了,可以直接黏贴到你的博文中了。

    Step5

  7. 只是此时这个链接实际上还没上传到github中,在浏览器中是无法访问的,这时候只要点提交并且上传等到上传成功后(如果之间是https模式clone的还要输入github的账号密码),就可以在浏览器中访问了!

    Step6

下载链接

下载链接 (jar版本和exe版本)

后记

该工具是基于javafx开发的,主要依赖于jGitJFoenix。如果有任何觉得需要改进的地方请留言或者在issue中提出,非常感谢!

GitHub地址:gitPic

原文地址:gitPic,利用Github做图床小工具

查看原文