:::

我讓CKEditor也可錄音了:Recordmp3js插件 / Recordmp3js Plugin: Record Voice in CKEditor

我讓CKEditor也可錄音了:Recordmp3js插件 / Recordmp3js Plugin: Record Voice in CKEditor

2014-09-06_004725

我做了CKEditor的插件Recordmp3js,這是以HTML5的新功能為基礎,建構在Recordmp3js專案上實作的插件。以下介紹這個套件的功能。

I developed a CKEditor pluing: Recordmp3js. This is based on HTML5 audio function and Recordmp3js project. You can use Recordmp3js plugin to record voice in CKEditor. This article introduce Recordmp3js and some development memo.


CKEditor插件:Recordmp3js / CKEditor Plugin: Recordmp3js

recordmp3js的特色如下:

  • 使用HTML5的錄音功能,不需要Flash或Java Applet等其他插件。
  • 錄音功能旁有個音量顯示器,可以知道自己的麥克風有沒有啟用或收到聲音。
  • 限制錄音長度:最短3秒,最長60秒。
  • 錄音檔案可以壓縮成MP3,而不是預設產生WAVE。
  • MP3檔案預設以Base64編碼儲存,也可以儲存到PHP File Host專案上。

安裝說明請看專案的README

使用介紹 / Usage

2014-09-06_005312

安裝好之後會看到一個麥克風的圖示gentleface.com free icon set

2014-09-06_012542 - copy

開啟視窗之後,要先按瀏覽器的「允許」麥克風。

PicPick 2014-09-06 01-23-32 2

然後主要操作介面才能正常啟用。左邊是錄音的按鈕,右邊是音量的顯示器,未開始錄音時是以單色顯示。讓我們按下錄音按鈕。

PicPick 2014-09-06 01-00-52 1

開始錄音。你可以看到限制錄音時間,右邊的音量顯示器變成彩色了。

PicPick 2014-09-06 01-36-14 5

停止錄音之後,要等待系統轉檔與上傳。大致上錄音1分鐘就需要1分鐘轉檔。

2014-09-06_004725

轉檔完成,下面會出現音樂播放界面。按下音樂下載圖示則可以下載錄音檔MP3music_down。錄音檔案的時間長度比實際錄音的時間還要長,這是已知的正常BUG (參考Known issues那段),目前沒有解決方法。

2014-09-06_014012

按下「確定」之後,就可以在編輯器內插入<audio>標籤了。

開發感想 / Development

萬用的Base64編碼 / Amazing Base64 Encoding

2014-09-06_100638

其實前一篇開發的PHP File Host專案是為了保存這篇的錄音檔而開發,規劃上是最後才實作。不過真的摸到Recordmp3js之後,才發現原來保存二進位MP3檔案的方式竟然是用Base64編碼!

Base64編碼是一種將二進位檔案以字串的方式編碼的方法。一般HTML網頁是以純文字的方式保存,因此網頁上面的圖片、聲音檔案等二進位資料通常是另外儲存,再以<img>、<audio>標籤嵌入到HTML網頁中。可是這個動作是撰寫HTML網頁初學者的第一個難關:為什麼網頁跟圖片要分開儲存?這也造成了複製網頁檔案的困難,不能只有複製HTML網頁檔案本身,還得複製相關使用的二進位圖片檔案。

Base64編碼可以讓圖片以字串的方式保存在HTML網頁中,而不需要額外保存一個檔案。我以前也介紹過以Base64編碼保存圖片這件事情。在寫這個Recordmp3js插件時,也因為覺得還要另外找地方插入麥克風圖示很麻煩,所以直接用Base64編碼的圖片來插入。可是我還真沒想到原來Recordmp3js的MP3聲音檔案也是用Base64來儲存!

以前只是單純地使用Base64編碼的檔案,但是到這時候我才意識到Base64的麻煩之處。一般是使用file類型表單欄位來上傳檔案,例如:

<input type=”file” name=”file” />

但是由於Base64編碼是字串資料形態,所以用普通的text類型表單欄位來遞交:

<input type=”text” name=”file” />

這兩者的name雖然都是file,但是對伺服器來說卻是不一樣的。在PHP當中前者是要用$_FILES[“file”]來取用、後者是要用$_POST[“file”]。此外,由於Base64編碼並沒有指定檔案名稱,所以還需要用另一個text欄位來傳送檔案名稱。

而即使Base64編碼是字串形式,也不能用JSONP的方式來做跨網域傳輸。因為JSONP實際上是將資料輸入在網址上,而Base64編碼的結果通常很容易超過網址的2083字元限制

這造成我得改寫PHP File Host的檔案接收方式,又花了我一番功夫。到最後索性乾脆讓Recordmp3js預設使用Base64編碼來儲存,讓PHP File Host變成選擇性支援。雖然這會造成插入CKEditor的資料變得超級長,但不需要額外架設伺服器保存MP3檔案這點還是蠻容易讓人使用的。

MP3轉檔 / MP3 Convert

一開始研究HTML5錄音功能時,最讓我困擾的地方在於HTML5預設的錄音結果是WAVE格式。WAVE是沒有壓縮的聲音檔案,因此聲音檔案的大小非常大,讓我難以直接使用HTML5的錄音功能來儲存錄音檔案。

本來還在考慮是否要在PHP File Host加上檔案轉檔功能,在上傳檔案之後轉檔成MP3或amr格式。可是後來意外發現Recordmp3js居然在Recorderjs專案之上加上了MP3轉檔libmp3lame.js的功能,讓MP3轉檔的工作直接就在客戶端瀏覽器上完成。這真的是太方便了。

當然,對很多網頁開發者來說,這是風險很高的事情。因為客戶端使用的瀏覽器跟電腦效能不一,因此完全不能寄望IE6或是在行動裝置上的瀏覽器能夠正常執行。我剛剛拿了Android的Chrome跟Firefox來玩玩看,的確是無法開啟。

不過我的應用場景比較特殊,我可以要求使用者以Chrome或Firefox來使用我的系統,這個顧慮就暫時不在我的考量之中。

其他的轉檔格式? / Other Better Audio Format?

這也讓我想到是否可能用更有效率的amr格式來為語音聲音檔案編碼,赫然發現GitHub上的確有amr.js專案,真是厲害。然而選用編碼格式也要顧慮到瀏覽器的支援,根據w3schools.com的HTLM5 Audio介紹,<audio>標籤只支援MP3、Wav跟Ogg格式,大部分瀏覽器都支援MP3,除了Opera。支援細節如下:

Browser MP3 Wav Ogg
Internet Explorer YES NO NO
Chrome YES YES YES
Firefox YES YES YES
Safari YES YES NO
Opera NO YES YES

 

HTML5的錄音元件 / Audio in HTML5

Recorderjs將HTML5的錄音元件包裝的非常好用,但是實際上使用之前,還是需要經過非常多的設定。你可以看看Recordmp3js的範例網頁程式碼,JavaScript設定那邊就一長串了,一開始研究的時候還真讓人感到困擾。Recordermp3js也具備了錄音完成之後上傳的功能,可是這功能卻寫死在Recordmp3js檔案裡面,而非開放設定的功能,讓我到最後還跑到Recordmp3js裡面去研究,也花了不少功夫。

在研究的過程中,越來越覺得audio真是有趣的應用。藉由結合多個音訊來源,我們可以動態控制各種聲音播放,就可以自行製作各種樂器。Web Audio Demos展示了很多聲音的應用,Web Audio Vocoder是其中一種強調混音的功能,這激起了很多不同應用的可能性。而我則是參考了AudioRecorer華麗的音量顯示器,做到Recordmp3js當中,讓錄音介面感覺漂亮一點。

錄音功能需要的Worker / Recorder and Worker

使用HTML5錄音跟MP3轉檔時,Recordmp3js都使用到了HTML5新元件Worker。一般來說,這個Worker必須是獨立的JavaScript程式碼,而且受限於同網域下執行的安全性問題。在跨網域應用中,這是一個很大的門檻。

但是我參考使用web workers這篇文章的說明,撰寫了worker_manger.js,將worker要執行的程式碼事先插入到目標網頁中,然後在以該網頁上的worker程式碼作為worker物件執行,就能夠保持在同網域執行的限制,迴避跨網域的問題。

雖然這個小功能我只用了很短的時間來做,但其實應該對很多人來說是很重要的功能吧?有機會再來正式發佈好了。

如何允許瀏覽器錄音 / How to Allow Browser Enable Microphone

使用HTML5錄音元件的另一個重點在於「允許」錄音檔案的事件。實際上啟用Recordmp3js的時候,跟HTML5元件宣告我要使用麥克風的時候,不是所有的瀏覽器就會跳出提示問你要不要啟用麥克風。

Firefox會在使用時直接跳出是否允許啟用,一個網頁只會問一次,Chrome有些版本也是如此。但是我電腦的Chrome卻不會在Recordmp3js載入時跳出來詢問,而是要離開網頁、再回到網頁時才會詢問。我索性加入一個<iframe>標籤,讓網頁觸發讀取事件,好讓Chrome問我要不要允許使用麥克風。但是離開網頁又回來時,Chrome還是會問我要不要允許麥克風,還好這動作也只要問一次而已。

很多使用者應該會忘記做「允許」麥克風這個動作。Chrome跟Firefox的介面都不太容易讓人理解,我可以預期這個動作應該是最讓人感到困擾的地方吧。

播放介面與<audio>標籤 / Audio Controller <audio> Tag

至於播放介面,我就直接使用HTML5的<audio>標籤。雖然<audio>標籤提供了播放/暫停、時間、播放進度條、聲音控制等功能,但是各個瀏覽器上<audio>長得都不太一樣,因此網路上大多建議是自行重寫<audio>的操作介面。但想到這個<audio>是要插入到CKEditor當中使用,寫得太複雜也不利於編輯。所以我還是選用最基本的<audio>標籤來顯示。

CKEditor插件開發 / About CKEditor Plugin Development

最後來講講CKEditor插件的開發。

一開始我是看为CKEditor在线编辑器增加一个自定义插件這篇,一步一步來實際操作看看。但是做到最後並沒有如期地做出可以用的CKEditor插件。我也去翻了CKEditor的Plugin教學跟它的API,但後來還是覺得乾脆直接複製既有的Plugin開始做起好了,所以就打開被壓縮的程式碼來看,直接從可以運作的功能中找尋我需要的程式片段。

雖然並不是什麼正規的學習方式,但這樣也在一片混亂中寫完了這個插件。有多混亂呢,看看插件的程式碼就知道了orz

總之最後還是完成了,也發佈到CKEditor的Add-on頁面去,也算是對這份研究有個交待啦!

話說回來,一開始會全部都重頭製作的原因就是因為在CKEditor與TinyMCE上找不到這種錄音的插件。現在我可以用這種方式來製作錄音插件的話,那其實像是webcam拍照與錄影等各種應用應該都沒問題才是。有機會再來研究看看吧。

(more...)

如何閱讀JavaScript/CSS壓縮程式碼?快使用程式碼格式化工具 / How to Maxify/Parsing/Format Minified Code

如何閱讀JavaScript/CSS壓縮程式碼?快使用程式碼格式化工具 / How to Maxify/Parsing/Format Minified Code

image

為了閱讀被壓縮(minify)的JavaScript與CSS程式碼,我們可以使用線上工具Code Formatter或是NetBeans的format指令來為程式碼進行排版。

You can use some tools to maxify/parse/format the minified JavaScript or CSS codes, for example, Online Code Formatter or NetBeans.


關於壓縮程式碼 / Minify Code

JavaScript與CSS程式碼的特性在於必須下載到使用者客戶端才能執行,因此降低程式碼的大小是很常見的方式。JavaScript跟CSS通常是以壓縮(minify)的形態發佈給大家使用。被壓縮的程式碼檔案名稱通常會加上「.min」,而原始碼通常會加上「.src」,舉例來說:

image

這是jQuery 1.11.1原始碼的樣子。檔案大小是276KB。

image

這是jQuery 1.11.1壓縮程式碼的樣子。檔案大小是93.5KB,幾乎是原始碼的1/3大小。

壓縮程式碼中會移除註解、刪除空白與換行、縮短變數名稱(例如變數用了var book,會縮短成var a)。我之前也介紹過使用YUI CompressorMinify壓縮程式碼的方法。而現在壓縮JavaScript跟CSS已經是主流用法,像是Fat-Free Framework中也直接內建了壓縮工具,非常方便。

為什麼要閱讀被壓縮的程式碼? / To Read Minified Code

雖然像是jQuery這種知名的函式庫會提供非壓縮的原始碼供大家閱讀研究,但是還是很多專案並沒有提供解壓縮的原始碼,而只有被壓縮的程式碼可以看。

我最近在研究如何撰寫CKeditor的plugin,可惜他的教學跟文件寫的並不是很好。後來我覺得比起研究文件,不如直接修改程式碼,說不定還比較快。

2014-09-05_164627

可惜的是,大部分CKeditor中plugin的程式碼都是壓縮後的結果,閱讀起來不太容易,我們需要一些解壓縮(maxify)工具來輔助我們閱讀這些程式碼。

在此介紹兩種格式化被壓縮程式碼的方便工具:NetBeans的format指令跟線上工具


NetBeans的格式化指令 / “Format” in NetBeans

我使用的是NetBeansIDE 8.0。要格式化被壓縮的JavaScript程式碼的做法如下:

  1. 開啟JavaScript檔案
    2014-09-05_170730
  2. 開啟Source > Format 
    2014-09-05_170801
  3. 變成了漂亮的排版
    2014-09-05_170855

不過你可以注意到下面還是有一團程式碼沒有解壓縮到,這似乎是NetBeans的限制。此外,NetBeans也不能解壓縮CSS程式碼,使用範圍有限。

使用Code Formatter解壓縮 / Maxify Code on Online Code Formatter

這個工具名稱叫做「Format, Beautify, Maxify, Unpack or Deobfuscate JavaScript/jQuery/HTML/JSON/CSS Codes」,有點長,還是用網址上的Code Formatter來稱呼好了。

image

這工具用法很簡單。首先先把壓縮的程式碼貼在框框中,然後按下下面的按鈕「Click here to Format/Beautify/Maxify Your JavaScript/jQuery/JSON//HTML Codes」。

image

程式碼就以漂亮的版面排版好了,而且NetBeans沒解開的後面部分也排版的漂漂亮亮,這樣就能夠更輕易地閱讀程式碼了,真是令人開心呢。

希望這些工具能夠幫助程式開發者更容易閱讀程式碼。學程式的第一步就是模仿別人怎麼寫,加油!

(more...)

PHP File Host 檔案上傳專案 / PHP File Host Project

PHP File Host 檔案上傳專案 / PHP File Host Project

圖片1

最近我完成了一個用PHP做的檔案上傳專案「PHP File Host」,順便學習了PHP框架Fat-Free Framework、PHP資料庫函式庫RedBeanPHP、前端檔案上傳工具jQuery File Upload跟前端界面Bootstrap等技術。以下說明這個專案內容。

I wrote a PHP project “PHP File Host” for cross origin file uploading. In this project, I try some new technology include Fat-Free Framework, RedBeanPHP, Bootstrap and jQuery File Upload. Following is introduction of this project.


專案由來 / Project Introduction

原本我的KALS專案並不具備檔案上傳功能(其實一開始規劃時有啦,但是一直沒有實作),但最近開始有了這方面的需求。然而檔案上傳乍聽之下很簡單,但是在跨網域(Cross Origin)的情境中,卻不太容易實作。

另一方面,簡單的檔案上傳應用實作常常會有幾個問題:

  1. 實體檔案管理的問題:檔案存放在哪哩?伺服器空間足夠嗎?
  2. 檔案重複問題:如何有效率地降低檔案的使用空間?
  3. 檔案名稱問題:遇到不支援的檔案名稱編碼,存到伺服器的檔案系統時會造成亂碼的問題。

因此我想要做一個簡單的檔案上傳應用網站。這個只做一件事情:支援跨網域的檔案上傳、然後的到一個下載網址。這樣就夠了。這就是PHP File Host的由來。

專案內容 / Project

圖片2

我把最近對PHP File Host的報告彙整成為一個投影片,裡面有簡單的功能介紹:

特色 / Features

PHP File Host的特色在於:

  • 運作環境:以PHP架設,資料庫預設使用SQLite,但是不需要額外配置資料庫。
  • 跨網域檔案上傳:支援以JSONP上傳jQuery File Upload上傳
  • 避免儲存重複檔案:以MD5特徵碼來辨識檔案內容,避免儲存相同檔案。
  • 完整保留檔案名稱:以資料庫儲存檔案名稱,並由程式負責從header指定下載檔案名稱,因此不會下載到亂碼的檔名。

相關技術 / Technology

裡面主要用到幾種技術,在此我也聊一下使用這些技術的心得。

Fat-Free Framework (F3)

Fat-Free Framework (F3)是一個PHP框架。不過在講F3之前,我想先聊一下CodeIgniter。

在開發KALS時,我主要使用的PHP框架是CodeIgniter (CI)。CI大量參考Ruby on Rails的理念,大量遵守「約定優於配置」(convention over configuration)的準則。特別是對於routing功能來說,要連到指定網址就得在特定的檔案結構中撰寫相對應的PHP類別。

一開始我覺得這也不錯,大家的都能遵守約定的話,開發就能夠維持一致性。但事實上是為了這這個約定,CI限制了大量的靈活性。常常會發現要接手專案的新手要花很多時間來瞭解routing的邏輯,而且無法自由指定routing中的變數與類別也很令人覺得限制很大。最致命的就是不能支援JSONP的呼叫模式,難以跟jQuery.getJSON()搭配運用。

雖然KALS的CI被我大改之後變得可以支援JSONP,但我不覺得這是一種理想的做法。所以當我這次要開發這個專門支援跨網域檔案上傳的PHP File Host時,我就毅然決然換了另一個PHP框架。

我花了一點時間嘗試不同的PHP框架,不過後來找到了F3。這個專案特色是檔案看起來不會太複雜,特別是與龐大的CodeIgniter相比。

image

F3一些零星的功能不多,但是主要功能卻比CI好用很多。

F3的routing是由設定檔控制,寫法跟Node.js的express框架很像。這符合我們一般使用的概念:從URI追溯檔案位置。而不是像CI那樣,得先瞭解約定才能知道檔案的位置。使用配置設定來規範routing這點看起來像是違反了「約定優於配置」,但是從另一個角度來看,這也是讓「使用者」(利用URI使用系統)跟「開發者」(使用伺服器上的檔案配置)脫鉤的一種好方法。CI那種routing規範實在是太過糾結,用起來綁手綁腳的。

而F3的routing也支援分辨GET (查詢)、POST (新增)、PUT (更新)、DELETE (刪除)等REST API會使用的四種方法。不過要注意到,若針對同一URI使用GET跟POST等多種方法,最後變數只會取得使用GET這個而已。這是比較令人困擾的地方,我得再研究看看。

此外,我喜歡F3用擴增HTML標籤的方式來建立樣板,輸出的樣板能夠直接指定MIME Type為JavaScript這點也很不錯,這對JSONP支援良好,也可以輕易使用現在流行的Markdown程式語言。相較之下,CI的樣板只能說是原始人。不過F3預設限制「同源使用」(same-origin),為此得額外宣告以下header才行讓其他網站跨網域開啟F3專案:

header('X-Frame-Options: ');

CI提供了大量零星的函式(helper),讓我們能夠簡單地處理很多小東西。F3並沒有這麼多helper,但是它把很多常用的系統與環境資訊都寫在框架的系統變數裡面。習慣之後也還算好用,但我比較喜歡helper的函式形式。

在資料庫的使用上,F3的資料庫也跟CodeIgniter的Active Record一樣,都是使用ORM (Object-Relation Mapping)的方式操作資料庫。而F3多了一些NoSQL資料庫的支援,像是MongoDBJig

雖然這些ORM用起來不錯,但是我這次更想使用另一種資料庫函式庫更感興趣,那就是RedBeanPHP。

RedBeanPHP

RedBeanPHP是一個PHP資料庫函式庫,使用時只要導入它一個PHP主要檔案即可。

他在使用上跟很多ORM函式庫一樣,可以把資料表當作一個類別,裡面的一列當作是一個物件來使用。但是最大的差別在於,RedBeanPHP是不需要預先設定資料表(schemaless)的架構。

舉例來說,今天我們有一種類別叫做Book,那我們就用RedBeanPHP建立一個類別叫做「Book」的物件,然後設定其中的屬性「title」跟「author」後儲存,這樣子資料庫中就會自動幫我們把相關的table與field都設定好,連field的資料形態都會與物件屬性的形態直接相對應。

未來如果這個Book想要增加第三種屬性「price」,那就在程式中加入「price」,儲存,這樣子資料表就會多一個price的欄位。

這樣子的好處在於,我們不需要在配置程式碼之餘還要煩惱如何配置資料庫。RedBeanPHP預設採用SQLite,但也可以支援主流的關聯式資料庫,如PostgreSQL跟MySQL。

我使用RedBeanPHP在PHP File Host中儲存檔案資料,操作起來非常容易上手,而且令人驚訝地好用。

有人抱怨RedBeanPHP的資料庫查詢速度過慢,這點可能要謹慎評估。但PHP File Host少量應用看來是沒有這個問題。

Bootstrap

這次我也一併改進了前端的界面。跟以往一樣,比起重頭開始設計網頁界面,我比較偏好從既有的網頁範本開始修改。難得這次機會,我也就從知名的客戶端技術Bootstrap的範本Landing Page開始改起。

使用Bootstrap的目的包括:

  • 支援RWD (Responsive Web Design):不論電腦、平板、手機等不同螢幕大小的裝置,網頁都應該自動最佳化調整版面。這點可以靠Bootstrap的Grid system來調整。
  • 一致且美觀的元件:Bootstrap的選單、按鈕、讀取條非常好看。我還蠻喜歡它的Default、Primary、Success、Info、Warning、Danger、Link的通用分類與對應顏色。
    image
  • 豐富的圖示:不光是Bootstrap本身提供了大量的圖示(Glyphicons),Landing Page範本還用了更多元的Font Awesome圖示,基本功能操作真的是不需要額外在準備其他圖片了。

圖片1

最後完成的結果在Am I Responsive?上看起來就是這樣,開頭的圖片會按照視窗畫面去做調整,頂端選單列也會在小螢幕中自動縮成一個按鈕,成果很不錯。

雖然我老是做一些伺服器端的專案,但是作為網頁相關的程式設計師,前端界面技術自然也不能生疏。PHP File Host雖然只是一個小小的網站,但是做起來還是令我挺開心的。

jQuery File Upload

我這次也加入了jQuery File Upload來改善檔案上傳的介面。這個套件可以用簡單的方式來設定檔案上傳的功能,讓我們輕易加入以下功能:

  • 點選按鈕、選擇檔案、馬上上傳
  • 上傳進度條
  • 拖曳至指定區域上傳
  • 剪貼上傳

我很喜歡這些方便的操作,傳統點選檔案按鈕的方式實在是太過麻煩。

另一方面,我本來還蠻煩惱怎麼用jQuery File Upload來進行跨網域傳送檔案,卻意外發現jQuery File Upload使用了HTML5元件postMessage來傳輸檔案的方式,比我以前提出的JSONP跨網域檔案上傳還要好用很多,真讓我驚豔。

不過最後我要在其他專案使用jQuery File Upload設定上傳功能時,卻發現它使用的是jQuery 1.11,與KALS專案的jQuery 1.4有很大的差別。加上jQuery File Upload也要使用jQuery UI等工具,導致它與其他功能互相衝突,最後我還是放棄在KALS專案使用jQuery File Upload而使用原本的JSONP跨網域檔案上傳方式。

向DSpace致敬 / Salute to DSpace

最後也提一下PHP File Host內部檔案儲存的方式,這部分我大量地參考了DSpace保存檔案的方式。

DSpace依照檔案的MD5特徵碼作為檔案名稱與實體位置的設定,因此每個檔案都長得像是「01f7b24e629cc23e369983994d0b8fbe」。檔案的名稱、MIME Type等相關資訊則是寫在資料庫中,連同上傳者、上傳時間等操作記錄也一併分開儲存。

這樣做可以改善檔案重複儲存、避免檔案名稱編碼不支援等問題,但是檔案管理 (特別是刪除)跟下載就成為另一個技術上的重點。目前PHP File Host還沒有做的刪除功能,就只是一直擺放資料,然後以供人下載而已。

利用Base56面碼縮短網址 / Shorten URL by Base56 Encoding

喔對了,為了避免網址過長,我還特別用了Base56將數字ID以「0123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ_-.~」等網址允許的字元進行編碼。即使檔案的編號很大,網址長度仍然不會很誇張地漲大。這種做法我也挺喜歡的。

這些大致上就是PHP File Host使用到的技術。


結語:過時的技術? / Conclusion: Outdated Technology?

剛好最近也看到一篇分析報導:「AngelList 分析:越好的公司越喜歡用 Python,越差的公司越愛用 PHP」。該分析將公司分成Okay、Good、Great三級,然後看公司使用的程式語言。

其中伺服器端PHP排行第三、客戶端Bootstrap排行第五(但是RoR我不認為是客戶端技術)、資料庫SQLite榜上無名。雖然直接看圖表起來也沒啥不好,但我現在才學這些技術,的確是比很多人慢了許多。

之後有機會的話,我想要研究伺服器端的Node.js,然後在單一頁面應用上繼續精進AngularJS (之前寫了一個批次開啟網頁的小應用,蠻好上手的)。久違地學習新的技術,真的很令人開心呢。

(more...)

為何Power Point插入圖片變得模糊了?勾選不要壓縮檔案中的影像 / Disable Power Point’s Image Compression Configuration to Avoid Blurring Images

布丁布丁吃布丁

為何Power Point插入圖片變得模糊了?勾選不要壓縮檔案中的影像 / Disable Power Point’s Image Compression Configuration to Avoid Blurring Images

2014-09-03_095441

如果你在Power Point插入圖片時,發現圖片變得模糊不堪使用,那就得啟用選項中的「不要壓縮檔案中的影像」來避免這個問題。

In Power Point, if you get a blurred image after inserting it, you should enable “Do Not Compress Images in File” at Power Point Options.


圖片模糊的問題 / Problem when Inserting Images

本文使用的是Power Point 2013,不過我在Power Point 2010上也會遇到相同的問題。

image

在做投影片的時候使用插入圖片時……

2014-09-03_095417

插入一張電腦截圖,可是圖片卻很小。

2014-09-03_095441

圖片放大之後模糊不堪使用。

網路上找了以下,從plumdumplings的回答中才知道原來是因為Power Point啟用了圖片壓縮的緣故。以下說明解法。

解決方法 / Solution

  1. 開啟Power Point的選項
    image
    image
  2. 到「進階」中,取消勾選「捨棄編輯資料」,並勾選「不要壓縮檔案中的影像」。
    2014-09-03_095557

這樣子重新插入圖片時,圖片解析度就不會被壓縮了。

2014-09-03_095642

這問題困擾了我好一陣子,不過網路上好像很少看到有人提起。在此跟大家分享。

(more...)