Monday, December 24, 2018

在Windows 10用Paint3D(小畫家3D)做浮水印

在Windows 10不用另裝軟體就可以做簡單的浮水印。拿跟Windows 10一起安裝的Paint3D(小畫家3D)就足夠了。
大致上分兩個步驟:
  1. 製作要當作浮水印的圖,如文字或商標等,背景要做成透明的。
  2. 把浮水印的圖放到圖片上,調整成半透明。
接下來我們一步一步來
  1. 在開始選單點開「小畫家3D」。
  2. 點選「新增」,我們先來做一張簡單的浮水印圖片。 
  3. 要先確定浮水印圖片的背景要是透明,按下上方的「畫布」按鈕。把右邊的「透明畫布」選項改成開啟。
    watermark-2.PNG
  4. 開始畫你理想中的浮水印。我這邊自己選了「2D 圖形」下的圓形畫了一個實心圓,再加入「文字」LOL。在小畫家3D中,上方功能按鈕被選擇後,所有相關功能設定都在視窗的右側。
  5. 把浮水印圖檔存起來,選左上角的「功能表」然後選「儲存」,輸入浮水印的檔案名稱。
  6. 現在把希望套上浮水印的圖片打開,選左上角的「功能表」然後選「開啟」下的「瀏覽檔案」,選擇要打開的圖片檔案。我挑了一張我家樓下貓的照片,因為我一直想把它蓋上浮水印占為己有。 menu.PNG

  7. 接下來終於要把浮水印放上來了,點選上方的「圖戳」按鈕,然後點右側檔案夾圖片的「自訂圖戳」頁籤。 sticker.PNG

  8. 選「新增圖戳」,然後在對話框中選剛剛做好的浮水印圖片。
  9. 現在可以看到浮水印蓋在圖片上了,也可以自由移動它的位置。不過在確定它的位置前,我們先把他調成半透明。在右邊有「圖戳不透明度」滑桿,將他越往左移就越透明。 watermark-3.PNG

  10. 確定好浮水印透明度跟位置後,按下浮水印右邊的勾勾符號就完成了。 watermark-4.PNG

Sunday, December 23, 2018

Windows Form 無法存取已處置的物件?

Go to English Verison

這到底發生了什麼事情?
System.ObjectDisposedException: 無法存取已處置的物件
很正常的,微軟的中文版錯誤訊息不只難懂還可能讓人搞錯方向。他對應的英文訊息是:
Cannot access a disposed object.
這邊說的「已處置」就是"disposed",某個物件被處置掉了所以不能夠再被使用。
會看到這個錯誤訊息八成是因為你要Show()一個已經被使用者關閉的Windows Form。使用者很有可能直接點了視窗右上角的關閉按鈕,造成Close()被呼叫,接著Dispose()就會被執行。最後這個被「處置」的Form就不能夠被用了,因為處置掉了嘛。
解決這問題不難,再new一個Form就好了,如果不確定要不要再建置一個新的Form,可以拿 IsDisposed 判斷。
if (form1?.IsDisposed == true)
{
    form1 = new Form1();
}
如果你真的不想讓Form關閉然後被處置掉,另一個作法是把Form藏起來。你可以在Closing事件阻止Form的關閉然後隱藏。
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = true; // 取消關閉作業
    Hide();          // 隱藏視窗
}

Saturday, December 22, 2018

Windows Form Cannot Access a Disposed Object?

閱讀中文版

What does this mean?
System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Form1'.
You are getting this exception probably because you want to Show() a windows form that was closed by user. The user likely closed the form by clicking the close button on the title bar. Close() is called when the form is closing and Dispose() is subsquently called. Now you have a disposed form that really not useful any more.
The fix is quite simple, just new the Form again. If you are not sure if the form has to be created again, check for IsDisposed.
if (form1?.IsDisposed == true)
{
    form1 = new Form1();
}
If you really want to hide the form instead of closing it and hence disposed, This is what you can do on the Closing event of the form.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = true; // Cancel the closing sequence
    Hide();          // Hide the form
}