
Sử dụng C# để viết một chương trình tạo Watermark (đóng dấu ảnh) đơn giản.
Một chương trình xử lý ảnh viết thời sinh viên, xem lại thấy gà quá
Chương trình minh họa tre6b Visual Studio 2005.
Tạo một project mới tên Watermark

Trên form chính (Form1.cs), thêm các components sau:
- Menu Strip: menuStrip1 chứa File > Open | Save | Exit
- Textbox: txtText dùng để chứa Watermark (chữ ký đóng dấu)
- ComboBox: cbFont chứa tên font
- Textbox: txtFontSize chứa kích thước font
- ComboBox: cbColor chứa tên màu chữ
- ComboBox: cbOptical chứa độ trong suốt của chữ (trong hình để nhầm là textbox)
- ComboBox: cbPosition chứa vị trí chữ (Trên, Giữa, Dưới)
- Button: btnOK thực hiện đóng dấu

Trong phần properties của Form1, thiết lập IsMdiContainer = True. Ta sẽ dùng Form1 làm nền, hình ảnh sẽ load vào một form con (FormImg.cs sẽ tạo sau), form con này bị chứa trong Form1 nhờ thuộc tính IsMdiContainer

Bổ sung thêm 2 components cho Form1 là:
- Open File Dialog
- Save File Dialog

Viết hàm cho sự kiện File > Open

Chú ý:
- bổ sung thư viện System.Drawing
- biến public pathImage dùng để lưu đường dẫn của hỉnh ảnh lúc mở file và lúc lưu file.
- Ta tạm viết phần comment // Do later , sau khi tạo FormImg sẽ viết tiếp

Viết hàm cho sự kiện File > Save

Tượng tự như trên, tạm viết tới commnet Do later.

Sự kiện File > Exit

Đơn giản.

Thêm tên Font

Thêm tên các font chữ tùy thích

Thêm màu sắc, ở đây chỉ ví dụ 3 màu

Độ trong suốt của chữ: hiện theo tỉ lệ %

Vị trí chữ sẽ đóng dấu trên hình, chỉ ví dụ 3 vị trí
Vì đây là một ví dụ minh họa đơn giản nên ta chỉ sử dụng các textbox, combobox để chứa các thuộc tính font,color,... người lập trình có thể cải tiến bằng cách tìm hiểu thêm cách dùng các components của Windows.

Tạo một form mới tên là FormImg, form này dùng để chứ hình ảnh khi ta mở/lưu/xử lý file hình.

Thêm biến Bitmap để chứa hình ảnh

Viết sự kiện Paint cho FormImg

Nội dung sự kiện Paint

Viết tiếp sự kiện Resize cho FormImg

Hàm này dùng để xóa buffer khi di chuyển hình ảnh trên FormImg

Quay lại Form1.cs (form chính)
Trong sự kiện File > Open bổ sung vào phần comment Do later sự kiện load hình ảnh từ file vào FormImg
Bây giờ nếu chạy thử chương trình, ta có thể mở hình ảnh lên được.

Tiếp tục bổ sung sự kiện lưu hình ảnh từ FormImg thành file
Giờ đây, ta có thể mở ảnh và lưu ảnh với 2 chức năng trên. Trong bài viết này chỉ minh họa việc tạo watermark, ta có thể viết nhiều cách xử lý ảnh khác nhau (tạo bóng nước, tổ chức đồ,...) dựa trên khung quản lý file này.

Cuối cùng ta viết sự kiện click chuột cho button OK.
private void btnOk_Click(object sender, EventArgs e)
{
try
{
// get image from FormImg to bmp
FormImg currentform = (FormImg)this.ActiveMdiChild;
Bitmap bmp = new Bitmap(currentform.bmp);
// get Font
string font = "Arial";
if (this.cbFont.Text != "Font")
font = this.cbFont.Text;
// get font size
int size = 19;
if (this.txtFontSize.Text != "Size")
size = int.Parse(txtFontSize.Text);
// get color
int color = 3; // white is default
if (cbColor.Text == "Black")
color = 1;
else if (cbColor.Text == "Red")
color = 2;
// get position
int wmPositon = 3; // bottom is default
if (cbPosition.Text == "Top")
wmPositon = 1;
else if (cbPosition.Text == "Middle")
wmPositon = 2;
// get optical
int wmOptical = 255; // bottom is default
if (cbOptical.Text == "50%")
wmOptical = 127;
else if (cbOptical.Text == "10%")
wmOptical = 25;
// set the watermark
Bitmap bmpNew = waterMark(bmp, txtText.Text, font, size, color, wmOptical, wmPositon);
// draw new image from bmp to FormImg
FormImg newForm = new FormImg(bmpNew);
newForm.MdiParent = this;
newForm.Show();
}
catch (Exception ie)
{
MessageBox.Show(ie.ToString());
}
}
Trong sự kiện trên, ta gọi hàm waterMark(bmp, txtText.Text, font, size, color, wmOptical, wmPositon)
Hàm waterMark(Bitmap bmPhoto, string txtWM, string wmFont, int wmSize, int wmMau, int wmTran, int wmViTri) này là hàm dùng đễ tạo watermark cho hình ảnh
private Bitmap waterMark(Bitmap bmPhoto, string txtWM, string wmFont, int wmSize, int wmMau, int wmTran, int wmViTri)
{
//create a image object containing the photograph to watermark
Image imgPhoto = bmPhoto;
int phWidth = imgPhoto.Width;
int phHeight = imgPhoto.Height;
//load the Bitmap into a Graphics object
Graphics grPhoto = Graphics.FromImage(bmPhoto);
//------------------------------------------------------------
//Step #1 - Insert Copyright message
//------------------------------------------------------------
//Set the rendering quality for this Graphics object
grPhoto.SmoothingMode = SmoothingMode.AntiAlias;
//Draws the photo Image object at original size to the graphics object.
grPhoto.DrawImage(
imgPhoto, // Photo Image object
new Rectangle(0, 0, phWidth, phHeight), // Rectangle structure
0, // x-coordinate of the portion of the source image to draw.
0, // y-coordinate of the portion of the source image to draw.
phWidth, // Width of the portion of the source image to draw.
phHeight, // Height of the portion of the source image to draw.
GraphicsUnit.Pixel); // Units of measure
//-------------------------------------------------------
//to maximize the size of the Copyright message we will
//test multiple Font sizes to determine the largest possible
//font we can use for the width of the Photograph
//define an array of point sizes you would like to consider as possibilities
//-------------------------------------------------------
Font crFont = WEB;
SizeF crSize = new SizeF();
//set a Font object to Arial (i)pt, Bold
crFont = new Font(wmFont, wmSize, FontStyle.Bold);
//Measure the Copyright string in this Font
crSize = grPhoto.MeasureString(txtWM, crFont);
//Since all photographs will have varying heights, determine a
//position 5% from the bottom of the image
int yPixlesFromBottom = (int)(phHeight * .05); // defaul is bottom
if (wmViTri == 1)
yPixlesFromBottom = (int)(phHeight * .95);
else if (wmViTri == 2)
yPixlesFromBottom = (int)(phHeight * .5);
//Now that we have a point size use the Copyrights string height
//to determine a y-coordinate to draw the string of the photograph
float yPosFromBottom = ((phHeight - yPixlesFromBottom) - (crSize.Height / 2));
//Determine its x-coordinate by calculating the center of the width of the image
float xCenterOfImg = (phWidth / 2);
//Define the text layout by setting the text alignment to centered
StringFormat StrFormat = new StringFormat();
StrFormat.Alignment = StringAlignment.Center;
// create shadow
//define a Brush which is semi trasparent black
// set Optical (Alpha set to 153)
SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(wmTran, 0, 0, 0));
//Draw the Copyright string
grPhoto.DrawString(txtWM, //string of text
crFont, //font
semiTransBrush2, //Brush
new PointF(xCenterOfImg + 1, yPosFromBottom + 1), //Position
StrFormat);
// Main TEXT
// white is default color
//define a Brush which is semi transparent white
// set Optical (Alpha set to 153)
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(wmTran, 255, 255, 255));
// black
if (wmMau == 1)
semiTransBrush = new SolidBrush(Color.FromArgb(wmTran, 0, 0, 0));
else
// red
if (wmMau == 2)
semiTransBrush = new SolidBrush(Color.FromArgb(wmTran, 255, 0, 0));
// draw TEXT again on a black background
//Draw the Copyright string a second time to create a shadow effect
//Make sure to move this text 1 pixel to the right and down 1 pixel
grPhoto.DrawString(txtWM, //string of text
crFont, //font
semiTransBrush, //Brush
new PointF(xCenterOfImg, yPosFromBottom), //Position
StrFormat); //Text alignment
//Replace the original photographs bitmap with the new Bitmap
// imgPhoto = bmPhoto;
grPhoto.Dispose();
return bmPhoto;
}

http://www.mediafire.com/?bx4d760pi17a8zk