2011年11月23日 星期三

使用C#實現縮圖功能

當我們的網站有提供使用者上傳圖片時,一般我們只會限制上傳圖檔類型,例如:.jpg、.png、.gif等,或者限制上傳圖檔的大小,至於圖檔的維度我們通常無法限制,原因是在於使用者並不是每個人都有能力針對圖檔進行編輯,所以為了讓使用者上傳的圖檔能符合網站設計,我們可以藉由img標籤裡的屬性width及height來設定,但這種設計的方式會有一個問題,當上傳的圖檔很大時多人同時瀏覽可能會耗費大量網站對外的頻寬影響系統其他使用者,所以比較好的作法是當上傳圖檔時除了原始圖檔外再產生一張縮圖,以下將說明我針對這個需求所撰寫的縮圖程式

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Web;

public class ImageUtility
{
    public ImageUtility()
    {

    }

    public static string ResizeImage(string strFilePath, int longSide)
    {
        float ratio;
        int width;
        int height;
        string suffix = "_s";
        string strDestFilePath;

        if (!File.Exists(strFilePath)) 
        {
            return "";
        }

        if (Path.GetExtension(strFilePath).ToLower() != ".jpg" &&
                Path.GetExtension(strFilePath).ToLower() != ".png" &&
                Path.GetExtension(strFilePath).ToLower() != ".gif") 
        {
            return "";
        }       

        Image img = System.Drawing.Image.FromFile(strFilePath);

        if (!(img.Width > longSide || img.Height > longSide))
        {
            return "";
        }

        if (img.Width > img.Height)
        {
            ratio = (float)longSide / img.Width;
        }
        else 
        {
            ratio = (float)longSide / img.Height;
        }

        width = (int)(img.Width * ratio);
        height = (int)(img.Height * ratio);

        Bitmap bmp = new Bitmap(img, new System.Drawing.Size(width, height));
        strDestFilePath = string.Format(@"{0}\{1}{2}{3}", Path.GetDirectoryName(strFilePath), Path.GetFileNameWithoutExtension(strFilePath), suffix, Path.GetExtension(strFilePath));
        bmp.Save(strDestFilePath);
        
        return strDestFilePath;
    }
}

這個靜態函式是接收原始圖檔目前所在的路徑並產生縮圖,而輸入參數longSide是指縮圖的長邊,舉例來說:如果原始圖檔是維度800X600的圖片,而longSide設定為100的話,那縮圖的維度就是100X75,以下整理函式處理步聚

  1. 檢查原始圖檔是否存在,如果不存在則中止處理。
  2. 檢查原始圖檔是否為.jpg、.png、.gif等格式,如果不是則中止處理。
  3. 當原始圖檔的長寬都小於指定的長度則中止處理。
  4. 以原始圖檔維度中較長的一邊做為縮圖基準,求得縮圖的比率進而得到縮圖後的長寬。
  5. 依得到的長寬產生縮圖,縮圖檔名為:原始檔名_s.副檔名。
上面函式適用於擺放圖檔的父容器是正方形,至於父容器如果是矩形就留待各位看倌思考。

2011年11月10日 星期四

使用javascript拖曳table內容

針對網頁內容進行拖曳相信有許多javascript library可以做到,底下將說明我目前使用的drag and drop javascript library,在實際說明前先說明我的網頁結構,網頁結構是以div包裝資料並放置在table裡的td,每個td代表div所在位置,而拖曳是要將div做位置搬移,以下為拖曳需求

  1. 不能拖曳資料到已含有其他拖曳物件(div)的td
  2. 某些td不可以被放置拖曳物件(div)
接著我們先來看head區塊的程式碼
<head>
    <title></title>
    <style type="text/css">
        .v_title_cell{width:20px; text-align:center; vertical-align:middle}
        .content{width:58px; height:58px; margin:auto; border-style:none; border-width:0px; color:White}
        .cell{width:60px; height:60px; text-align:center; vertical-align:middle}
    </style>
    <script type="text/javascript" src="drag-min.js"></script>
    <script type="text/javascript">
        window.onload = function () {
            rd = REDIPS.drag; // reference to the REDIPS.drag class
            // initialization
            rd.init();
            // set hover color
            rd.hover_color = '#9BB3DA';           

            // this function (event handler) is called after element is dropped
            REDIPS.drag.myhandler_dropped = function () {

            }
        }
    </script>
</head>
在head區塊裡有二個地方是一定要撰寫的,第一個是加入drag-min.js檔案,可以點選這裡下載,下載後解壓縮可以在REDIPS_drag目錄下看到redips-drag.js及redips-drag-min.js檔案,擇一引用即可,目前我是引用redips-drag-min.js檔案並將它改名為drag-min.js,另一個要撰寫的是在window.onload事件裡撰寫REDIPS.drag物件的建立及初始,在上面範例有個myhandler_dropped事件,它是指進行拖曳完成後(無論最後是否有改變位置)要引發什麼,更詳細的說明請參考線上文件

接下來我們來看body區塊的程式碼
<body>
    <div id="drag">
        <table style="text-align:center; width:260px; margin:auto" border="1">
            <tr>
                <td class="mark"></td>
                <td class="mark">1</td>
                <td class="mark">2</td>
                <td class="mark">3</td>
            </tr>
            <tr>
                <td class='v_title_cell mark'>2</td>
                <td class="cell single">
                    <div class="content drag" style="background-color:Red">紅</div>
                </td>
                <td class="cell single"></td>
                <td class="cell single"></td>
            </tr>
            <tr>
                <td class='v_title_cell mark'>3</td>
                <td class="cell single">
                    <div class="content drag" style="background-color:Blue">藍</div>
                </td>
                <td class="cell single"></td>
                <td class="cell single"></td>
            </tr>
            <tr>
                <td class='v_title_cell mark'>4</td>
                <td class="cell single">
                    <div class="content drag" style="background-color:Green">綠</div>
                </td>
                <td class="cell single"></td>
                <td class="cell single"></td>
            </tr>
        </table>
    </div>
</body>
body區塊有幾個地方要注意的

  1. table必須放在id名稱為drag的div裡
  2. 如果td不允許放置拖曳物件(div)則class要加上mark
  3. 如果td只允許放置一個拖曳物件(div)則class要加上single
  4. 如果div要成為可拖曳的物件必須在class加上drag

下圖是網頁呈現畫面


下圖為拖曳時的畫面


更多詳細資料請參閱底下連結
http://www.redips.net/javascript/drag-and-drop-table-content/

2011年11月9日 星期三

依據圖片大小自動調整popup window大小

撰寫此篇的源由是目前負責的系統有提供使用者上傳圖片,在未撰寫上傳圖片自動依據長邊縮圖的功能下,只針對前端的img標籤設定寬度及高度,所以使用者在觀看網頁時實際上是下載圖片後再做縮小以達到縮圖效果,那為了讓使用者能觀看原本圖片的原貌則提供了點撃縮圖彈跳出原圖視窗,在這裡有二個需求
  1. popup window希望開啟後能置中
  2. popup window的大小希望能依據圖片實際大小縮放
以下針對部份程式碼做相關說明


當我們為img設定屬性width及height時我們無法取得圖片的實際寬度及高度,所以這裡需要做一些處理,處理步驟
  1. Step1 以二個變數暫存目前縮圖的寬度及高度。
  2. Step2 移除目前縮圖的寬度及高度,目的在取得實際圖片的寛度及高度,並利用二個全域變數暫存實際寬度及高度。
  3. Step3 將Step1取得的寬度及高度回存到圖片物件。
至於為什麼要利用$(window).load而不利用$(document).ready請參考文章最後的相關連結,至於視窗置中部份因為我們的視窗等於圖片的大小,所以只要利螢幕長寬減去實際圖片的長寬除2即可得知未來視窗要放置的位置。

參考

2011年10月5日 星期三

中文斷詞系統使用

在文字探勘中斷詞斷字是資料處理的重要步驟,英文句子我們可以藉由空白取得句中的每個單字,但中文句子因為沒有分隔符號所以我們無法藉由程式自動化處理取得句中的字或詞,所幸中研院有研發中文斷詞系統,本篇將介紹如何申請及使用

首先我們先連結到中文斷詞系統的網址


進入畫面後,我們可以看到左方選單有個線上服務申請的連結,點選後右方畫面此時會更新並出現按此申請的字樣


填寫相關資訊並勾選我同意本服務條款及前述注意事項後按下送出按鈕


接著進入填寫相關資訊時所留的電子信箱,此時會收到啟動確認信函,點撃信件中的此處即完成服務申請


由於中文斷詞系統是經由TCP Socket傳送相關資料,我們必須撰寫Socket Client程式或直接使用中文斷詞系統網站上的斷詞服務客戶程式,這裡我們只介紹斷詞服務客戶程式,首先我們可以看到網頁左方有個線上資源連結,點選後右方會出現下載斷詞服務客戶程式(console)字樣,點選連結下載即可


下載後解壓縮我們可以得到下面的目錄及檔案


其中ckipsocket.propeties是設定檔,裡面記載著中文斷詞系統的IP、通訊埠、帳號、密碼...等,
帳號及密碼是之前申請服務時所填寫的申請帳號及申請密碼,host及port請不要變更這二項是固定的,更詳細的說明請參酌README.txt


在目錄Text中有二個資料夾,input資料夾所儲放的是要送往中文斷詞系統進行斷詞處理的文件,而文件的個數可以是一個或多個,output資料夾則是中文斷詞系統處理後回傳的結果文件,結果文件內容是以全型空白作為詞與詞的分隔符號,至於是否可以自行定義目錄結構或目錄名稱,答案是可以的,我們可以參考test.bat的內容
CkipClient.exe ckipsocket.propeties Text\input Text\output
CkipClient.exe是主程式
ckipsocket.propeties是設定檔
Text\input是預設的input資料夾
Text\output是預設的output資料夾

最後我們以財政部2011-11-10新聞稿「民眾檢舉逃漏稅應提出明確具體事證」部份內容並刪除標點符號作為我們實驗裡input的資料












然後執行test.bat
































接著我們會在output資料夾看到與input資料相同檔名的文件,以下為文件內容















每個詞後面是詞類標記,而(N)一般來說代表名詞,詳細詞類標記可至中文斷詞系統裡的詞類標記列表下載

2011年9月22日 星期四

淺談資料庫實體檔案搬移(3)

延續上篇現在我們來看第三種方法
方法三:利用T-SQL語法
首先我們利用T-SQL語法查詢Northwind資料庫的相關資料


--database_id DB的ID
--name 邏輯名稱
--physical_name 實際檔案儲存位置
SELECT database_id, name, physical_name
FROM sys.master_files
WHERE database_id = DB_ID('Northwind');


從查詢結果我們可以得知Northwind資料庫的DB ID、邏輯名稱及實際檔案儲存位置,接著我們要變更實際檔案儲存位置,由C:\SQL Server 2000 Sample Databases目錄改為D:\SQL Server 2000 Sample Databases目錄,執行以下語法可以完成目錄變更


--變更檔案儲存位置
ALTER DATABASE Northwind
MODIFY FILE (NAME = Northwind, FILENAME = 'D:\SQL Server 2000 Sample Databases\Northwind.mdf');

ALTER DATABASE Northwind
MODIFY FILE (NAME = Northwind_log, FILENAME = 'D:\SQL Server 2000 Sample Databases\Northwind_log.ldf');

這裡要注意的是完成語法只是代表系統目錄已修改Northwind資料庫的檔案路徑,但實際檔案還是要自己將Northwind.mdf及Northwind_log.ldf從C:\SQL Server 2000 Sample Databases目錄移至D:\SQL Server 2000 Sample Databases目錄


為了能搬移檔案我們執行資料庫離線語法

USE master
--設定離線
ALTER DATABASE Northwind SET OFFLINE


執行後我們才可以搬移Northwind.mdf及Northwind_log.ldf到D:\SQL Server 2000 Sample Databases目錄,搬移完成後再執行資料庫在線語法


USE master
--設定在線
ALTER DATABASE Northwind SET ONLINE

最後我們再利用語法檢查


--database_id DB的ID
--name 邏輯名稱
--physical_name 實際檔案儲存位置
SELECT database_id, name, physical_name
FROM sys.master_files
WHERE database_id = DB_ID('Northwind');


至於Detach/Attach與ALTER DATABASE的不同可點參考,最後還是再提醒讀者這一系列的發文只針對單純的個人使用環境不適用於複雜營運中的資料庫。




淺談資料庫實體檔案搬移(2)

延續上篇我們現在來看第二種方法
方法二:利用備份、還原方式
整個流程是先備份Northwind資料庫再刪除Northwind資料庫,刪除Northwind資料庫的目的在於移除C:\SQL Server 2000 Sample Databases目錄下的NORTHWND.MDF及NORTHWND.LDF,接著我們建立同名資料庫並將路徑選擇在D:\SQL Server 2000 Sample Databases目錄,最後再將備份檔還原,以下為操作說明及圖示,首先選取Northwind資料庫,按滑鼠右鍵選取[工作(T)]並點選[備份(B)...]




接著我們為備份檔命名及指定存放路徑








接著我們刪除原先的Northwind資料庫


再新增同名資料庫,並將路徑指定於D:\SQL Server 2000 Sample Databases目錄




此時我們可以看到D:\SQL Server 2000 Sample Databases目錄下產出Northwind.mdf及Northwind_log.ldf



接著我們再將備份檔還原到新建的Northwind資料庫,先點選Northwind資料庫接著按滑鼠右鍵選取[工作(T)],選取[工作(T)]後再選取[還原(R)],最後點選[資料庫(D)]


還原來源選取D:\SQL Server 2000 Sample Databases目錄的備份檔




最後只要選取[選項]頁面並勾選[覆寫現有的資料庫]再按[確定]鈕即可




如果我們的實體磁碟機有二顆以上,在備份時可將備份檔指定放在資料庫所在磁碟之外的磁碟,可加速備份及還原主要能加速的原因是減少硬碟I/O的爭用。


下篇

2011年9月19日 星期一

淺談資料庫實體檔案搬移(1)

撰寫這篇的原因起於同學在使用MS SQL上的問題,同學的實驗環境中資料庫實體檔案是儲存在C磁碟槽,但目前C磁碟槽剩餘空間不足,無法應付後續資料的成長,所以想將資料庫搬移至D磁碟槽,因此我提出了三個搬移方式,至於運作於商業環境的資料庫使用者,則請忽略此篇文章,因為商業環境的資料庫搬移需要更細膩的策略這裡不探討,底下為Demo環境及三個搬移方式說明:

OS:Windows XP Professional Service Pack 3
DBMS:SQL Server 2005 Developer Edition
DB:Northwind

方法一:利用卸離、附加方式
一般來說我們無法搬移正在使用中的使用者資料庫,必須先將資料庫卸離後才能移動資料庫,否則將會出現下圖的錯誤


我們要將Northwind資料庫的實體檔案從C:\SQL Server 2000 Sample Databases目錄移至D:\SQL Server 2000 Sample Databases目錄,首先我們先點選Northwind資料庫,再點選滑鼠右鍵並移至[工作]選擇[卸離]


當資料庫卸離後我們可以搬移檔案到D:\SQL Server 2000 Sample Databases目錄,搬移的檔案包含資料庫的mdf檔及ldf檔


搬移完成後,我們要附加資料庫,我們先點選[資料庫]再按右鍵選取[附加]

此時會出現挑選畫面,按下[加入(A)...]挑選D:\SQL Server 2000 Sample Databases目錄下的NORTHWND.MDF,最後按下[確定]



最後我們再來檢視一下附加後的Northwind資料庫檔案路徑,點選Northwind資料庫後,按滑鼠右鍵並選擇[屬性],在屬性視窗中選擇[檔案]頁面


下篇

2011年9月10日 星期六

IdeaSparks ASP.NET CoolControls簡介

IdeaSparks ASP.NET CoolControls是什麼東西?它是一個擴充自GridView的元件,
也意謂著在使用這個元件時基本的運用方式就像GridView一樣簡單使用,好處
就是學習門檻低,那到底IdeaSparks ASP.NET CoolControls提供什麼額外的功能
?這裡我引述作者官方blog所列功能
  1. Fixed column header, footer and pager
  2. Scrollable content
  3. User-resizeable column widths (new!)
  4. Maintains scroll position and column widths after a postback or callback (new!)
接著我會以Visual Studio 2010 Professional加上北風資料庫做Demo

Step 1:將IdeaSparx.CoolControls.Web.dll放到專案的Bin目錄,在這裡我的專案
類型是Web Site,放置Bin目錄後專案會自行參考


Step2:接著我們要為Toolbox增加CoolControls,首先我們點選Standard tab再按滑鼠右鍵,選擇Choose Items,選取之前放置在Bin目錄的IdeaSparx.CoolControls.Web.dll




Step3:將畫面切換至Design模式,並將CoolGridView托曳至畫面,這裡資料來源是使用SqlDataSource方式連結北風資料庫的Customers資料表



Step4:執行
IE 6

Firefox 6.0.2

Chrome 13.0.782.220

從畫面看來在主流瀏覽器顯示固定表頭功能都能正常運作,接著我們來嘗試Column Resize的功能,讓CompanyName及Country的欄位變寛靠近捲軸,這裡只顯示IE 6的結果

變更欄位寛度過程

變更後結果

至於其餘細節讀者可自行研究,底下是元件作者的blog