private Point unScale(Point scaledP)
{
if (picturebox1.SizeMode != PictureBoxSizeMode.Zoom) //only zoom mode need to scale
return scaledP;
Point unscaled_p = new Point();
// image and container dimensions
int w_i = picturebox1.Image.Width;
int h_i = picturebox1.Image.Height;
int w_c = picturebox1.Width;
int h_c = picturebox1.Height;
float imageRatio = w_i / (float)h_i; // image W:H ratio
float containerRatio = w_c / (float)h_c; // container W:H ratio
if (imageRatio >= containerRatio)
{
// horizontal image
float scaleFactor = w_c / (float)w_i;
float scaledHeight = h_i * scaleFactor;
// calculate gap between top of container and top of image
float filler = Math.Abs(h_c - scaledHeight) / 2;
unscaled_p.X = (int)(scaledP.X / scaleFactor);
unscaled_p.Y = (int)((scaledP.Y - filler) / scaleFactor);
}
else
{
// vertical image
float scaleFactor = h_c / (float)h_i;
float scaledWidth = w_i * scaleFactor;
float filler = Math.Abs(w_c - scaledWidth) / 2;
unscaled_p.X = (int)((scaledP.X - filler) / scaleFactor);
unscaled_p.Y = (int)(scaledP.Y / scaleFactor);
}
return unscaled_p;
}
上色
Code Block
2015年7月25日 星期六
[C#] 取得picture box在zoom模式時的正確圖片座標
2015年7月22日 星期三
[C#] Rotate bitmap with a special angle
public unsafe void Rotate(Bitmap bmp, float angle)
{
int width=bmp.Width;
int height=bmp.Height;
/*
* right, down = positive
* p1------------p2
* | |
* p4------------p3
*
* p1(0,0), p2(width-1,0), p3(width-1,height-1), p4(0,height-1)
*
* In this coordinate system(left-handed coordinate system), clockwise rotation matrix (theta): (cos -sin
* sin cos)
*
*/
//Calculate new vertex
Point p1 = RotatePoint(new Point(0, 0), angle);
Point p2 = RotatePoint(new Point(width - 1, 0), angle);
Point p3 = RotatePoint(new Point(width - 1, height - 1), angle);
Point p4 = RotatePoint(new Point(0, height - 1), angle);
//Calculate new size
int dstWidth = Math.Max(Math.Abs(p3.X - p1.X) + 1, Math.Abs(p4.X - p2.X) + 1);
int dstHeight = Math.Max(Math.Abs(p3.Y - p1.X) + 1, Math.Abs(p4.Y - p2.Y) + 1);
/*
* Calculate offset between old and new coordinate system
* left-top point in new coordiante system -> (0,0)
*
*/
int offsetX = -new int[4] { p1.X, p2.X, p3.X, p4.X }.Min();
int offsetY = -new int[4] { p1.Y, p2.Y, p3.Y, p4.Y }.Min();
//create bmp
Bitmap dstBitmap = new Bitmap(dstWidth, dstHeight, PixelFormat.Format32bppArgb);
Rectangle srcRect = new Rectangle(0, 0, width, height);
Rectangle dstRect = new Rectangle(0, 0, dstWidth, dstHeight);
BitmapData srcBmpData = bmp.LockBits(srcRect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData dstBmpData = dstBitmap.LockBits(dstRect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
//define sin and cos
double sin = Math.Sin(angle * Math.PI / 180);
double cos = Math.Cos(angle * Math.PI / 180);
int srcStride = srcBmpData.Stride;
int dstStride = dstBmpData.Stride;
//define pointer
byte* srcP = (byte*)srcBmpData.Scan0.ToPointer();
byte* dstP = (byte*)dstBmpData.Scan0.ToPointer();
Parallel.For(0,dstHeight,i=>
{
Parallel.For(0, dstWidth, j =>
{
int k = 4 * j + i * dstStride;
//Calculate corresponding point in old coordinate system
Point oldPoint = RotatePoint(new Point(j - offsetX, i - offsetY), -angle);
if (oldPoint.X >= 0 && oldPoint.X < width && oldPoint.Y >= 0 && oldPoint.Y < height)
{
dstP[k] = srcP[4 * oldPoint.X + srcStride * oldPoint.Y];
dstP[k + 1] = srcP[4 * oldPoint.X + srcStride * oldPoint.Y + 1];
dstP[k + 2] = srcP[4 * oldPoint.X + srcStride * oldPoint.Y + 2];
dstP[k + 3] = srcP[4 * oldPoint.X + srcStride * oldPoint.Y + 3];
}
else
{
dstP[k] = dstP[k + 1] = dstP[k + 2] = 0xff;
dstP[k + 3] = 0x0;
}
});
});
bmp.UnlockBits(srcBmpData);
dstBitmap.UnlockBits(dstBmpData);
bmp = (Bitmap)dstBitmap.Clone();
dstBitmap.Dispose();
width = bmp.Width;
height = bmp.Height;
}
2015年6月17日 星期三
[Android] commit()與apply()
SharedPreferences.Editor中的commit()與apply()都是向SharedPreferences寫入數據,差別如下︰
commit()︰立刻同步寫入數據到磁碟中的SharedPreferences,並且具有回傳值(boolean)表示成功或失敗
apply()︰API 9之後加入的method,會將欲寫入的數據暫存於記憶體中,進行一個非同步寫入,因此速度較commit()快,但是不具有傳回值
因此假如不需要傳回值的時候,建議使用apply()取代commit()
Android Developer的解釋如下︰
commit()︰立刻同步寫入數據到磁碟中的SharedPreferences,並且具有回傳值(boolean)表示成功或失敗
apply()︰API 9之後加入的method,會將欲寫入的數據暫存於記憶體中,進行一個非同步寫入,因此速度較commit()快,但是不具有傳回值
因此假如不需要傳回值的時候,建議使用apply()取代commit()
Android Developer的解釋如下︰
Reference: http://developer.android.com/reference/android/content/SharedPreferences.Editor.htmlAs SharedPreferences instances are singletons within a process, it's safe to replace any instance of commit() with apply() if you were already ignoring the return value.You don't need to worry about Android component lifecycles and their interaction with apply() writing to disk. The framework makes sure in-flight disk writes from apply() complete before switching states.
2015年6月13日 星期六
[Windows] Windows 7 / Windows 8破解使用者密碼
若是連Administrator都被密碼鎖住無法登入,可依照以下方法破解︰
1. 使用任何可開機裝置進入系統(Windows安裝光碟->修復主控台、Windows PE、MS-DOS with NTFS support、Linux),只要可以操作檔案系統即可
2. 輸入以下命令將放大鏡工具改為命令提示字元(Command Prompt)︰
c: (或是你安裝windows的硬碟代號,不一定是c)
cd windows\system32
ren Magnify.exe Magnify1.exe (將原本的放大鏡程式改名)
ren cmd.exe Magnify.exe (將命令提示字元改名為放大鏡)
3. 重新開機,進入Windows 7登入畫面
4. 點選左下角的「輕鬆存取」,勾選「讓螢幕上的項目放大一些(放大鏡)」,按下「確定」,即可開啟命令提示字元(Command Prompt)
5. 輸入以下命令,創建一個具有系統管理員身份的帳戶︰
net user test123 /add
net localgroup administrators test123 /add
以上兩行命令代表創建一個test123的帳戶,並賦予系統管理員權限
6. 以剛剛創立的test123帳戶即可成功登入系統
7. 輸入以下命令,還原放大鏡工具︰
ren Magnify.exe cmd.exe
ren Magnify1.exe Magnify.exe
8. 進入「控制台」->「使用者帳戶」-> [原本的使用者] -> 「移除密碼」
9. 登入後即可以原本的使用者登入(不需密碼)
1. 使用任何可開機裝置進入系統(Windows安裝光碟->修復主控台、Windows PE、MS-DOS with NTFS support、Linux),只要可以操作檔案系統即可
2. 輸入以下命令將放大鏡工具改為命令提示字元(Command Prompt)︰
c: (或是你安裝windows的硬碟代號,不一定是c)
cd windows\system32
ren Magnify.exe Magnify1.exe (將原本的放大鏡程式改名)
ren cmd.exe Magnify.exe (將命令提示字元改名為放大鏡)
3. 重新開機,進入Windows 7登入畫面
4. 點選左下角的「輕鬆存取」,勾選「讓螢幕上的項目放大一些(放大鏡)」,按下「確定」,即可開啟命令提示字元(Command Prompt)
5. 輸入以下命令,創建一個具有系統管理員身份的帳戶︰
net user test123 /add
net localgroup administrators test123 /add
以上兩行命令代表創建一個test123的帳戶,並賦予系統管理員權限
6. 以剛剛創立的test123帳戶即可成功登入系統
7. 輸入以下命令,還原放大鏡工具︰
ren Magnify.exe cmd.exe
ren Magnify1.exe Magnify.exe
8. 進入「控制台」->「使用者帳戶」-> [原本的使用者] -> 「移除密碼」
9. 登入後即可以原本的使用者登入(不需密碼)
2015年6月10日 星期三
[Android] Custom ListView with SimpleAdapter
若要以SimpleAdapter建立包含RadioButton或是CheckBox的Custom ListView,可依照以下方法︰
1. 將ListView中將各元件設定為以下屬性
2. 建立一個變數以管理RadioButton或是CheckBox的狀態
3. 建立ListView的OnItemClickListener方法以管理RadioButton或是CheckBox的狀態
Example:
依照以下格式設定資料來源
Title: 主標題
Content: 副標題(內容)
Checked: 核取狀態(true / false)
最後需要取得資料時,直接判斷ArrayList中HashMap的Checked欄位即可得知被選取的資料
android:focusable="false" android:focusableInTouchMode="false" android:clickable="false"
2. 建立一個變數以管理RadioButton或是CheckBox的狀態
3. 建立ListView的OnItemClickListener方法以管理RadioButton或是CheckBox的狀態
Example:
//Create data private ArrayList<<HashMap<String, Object>> itemList;
依照以下格式設定資料來源
Title: 主標題
Content: 副標題(內容)
Checked: 核取狀態(true / false)
final SimpleAdapter simpleAdapter = new SimpleAdapter(this,itemList,R.layout.customListView,new String[]{"Title","Content","Checked"},new int[]{R.id.TextView1,R.id.TextView2,R.id.RadioButton1});
simpleAdapter.setViewBinder(new SimpleAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Object data, String textRepresentation) {
//Hide empty textView
if (data == null) {
view.setVisibility(View.GONE);
return true;
}
view.setVisibility(View.VISIBLE);
return false;
}
});
ListView listview = (ListView) findViewById(R.id.ListView1);
listview .setAdapter(simpleAdapter);
listview .setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
RadioButton radiobutton1 = (RadioButton) findViewById(R.id.RadioButton1);
//Save position
for (HashMap<String, Object> data : itemList)
data.put("Checked", false); //Clear state
itemList.get(position).put("Checked", true); //Set current radio button to checked
simpleAdapter.notifyDataSetChanged();
}
});
最後需要取得資料時,直接判斷ArrayList中HashMap的Checked欄位即可得知被選取的資料
[Android] 將App從「最近App列表」中隱藏
1. 在AndroidManifest.xml中加入以下屬性
<activity> ... android:excludeFromRecents="true" ... </activity>或是以intent啟動activity時加入以下屬性
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);2. 在AndroidManifest.xml中加入以下屬性
<activity> ... android:label="" ... </activity>
訂閱:
意見 (Atom)
