巧用PhotoChooserTask选择器,完成字体文件文本文件的同步

 

      学习了文章《巧用PhotoChooserTask选择器,制作本地TXT阅读器》后,感觉这种方法非常巧妙,正好我正在写两个WP7应用《OOK随心所写》和《OOK随心所读》,《OOK随心所写》是一款用来临摹练习硬笔字的应用,而《OOK随心所读》则是用来阅读电子书的应用。两个应用需要用到与PC端同步数据的功能,本打算使用WCF的方法进行数据传输。阅读这篇文章后,觉得暂时还是用这么方法比较方便一点。于是根据这篇文章做了一个字体文件(*.ttf)和文本文件(*.txt)的同步应用,并使用于正在开发的《OOK随心所写》和《OOK随心所读》软件中。

1、处理本地文件

      PC端我使用了WinForm作为本地文件处理的客户端,软件界面如下:

      首先,分析字体信息:

分析字体文件信息
        /// <summary>
/// 打开字体文件
/// </summary>
private void btnOpenFile_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "TTF文件 (*.TTF)|*.TTF"; //上传格式

if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
this.txtPath.Text = openFileDialog1.FileName;//文件路径
fontEntity.FontFileName = lblFileName.Text = Path.GetFileName(openFileDialog1.FileName);
SetFontInfo(File.ReadAllBytes(txtPath.Text));
}
}

/// <summary>
/// 分析字体文件信息
/// </summary>
private void SetFontInfo(byte[] fontByteArray)
{
PrivateFontCollection fc = new PrivateFontCollection();
IntPtr pointer = Marshal.UnsafeAddrOfPinnedArrayElement(fontByteArray, 0);
fc.AddMemoryFont(pointer, Convert.ToInt32(fontByteArray.Length));

System.Drawing.Font f = new System.Drawing.Font(fc.Families[0], 38);
FontFamily ff = f.FontFamily;

fontEntity.FontEnglishName = lblEnglish.Text = ff.GetName(1033);
fontEntity.FontChineseName = lblChineseName.Text = ff.Name;
fontEntity.FontLenght = fontByteArray.Length.ToString();
Application.DoEvents();
SetFontPic(f);

lblChineseName.Font = f;
}

 

      接着,生成一张原始的字体信息图片:

生成一张原始的字体图片
        /// <summary>
/// 生成一张原始的字体图片
/// </summary>
private void SetFontPic(Font f)
{
Bitmap myBmp = new Bitmap(240, 400);
Graphics g = Graphics.FromImage(myBmp);//创建位图图形对象
g.Clear(Color.AliceBlue);
g.SmoothingMode = SmoothingMode.HighQuality;
// Create a text string, a Font object, and a StringFormat object
String s = "OOK随心系列 字体上传专用图片";
String s2 = f.Name;
StringFormat sf = new StringFormat(StringFormatFlags.DirectionVertical);
Font f2 = new Font("Times New Roman", 14);

g.DrawString(s, f2, Brushes.Black, 10, 10, sf);
g.DrawString(s2, f, Brushes.Black, 100, 30, sf);

myBmp.Save("FontPic.jpg", ImageFormat.Jpeg);
myBmp.Dispose();
f.Dispose();
g.Dispose();
}

 

      最后,把原始的图片混合字体信息和字体文件后生成带字体文件的图片:

生成最终带字体文件的图片
         /// <summary>
/// 生成最终带字体文件的图片
/// </summary>
private void btnGenPic_Click(object sender, EventArgs e)
{
string path = txtPath.Text.Trim();
if (string.IsNullOrEmpty(path))
{
MessageBox.Show("请先选择一个字体文件!", "提示");
return;
}

GenFontPic();
}

/// <summary>
/// 生成一张加入头信息和字体文件的图片
/// </summary>
private void GenFontPic()
{
// 读取图片
byte[] imageArray = File.ReadAllBytes("FontPic.jpg");
fontEntity.FontPicLenght = imageArray.Length.ToString();

//读取字体信息
string headInfo = fontEntity.ToString();
byte[] headerArray = Encoding.UTF8.GetBytes(headInfo);

//读取字体文件
Byte[] fontByteArray = File.ReadAllBytes(txtPath.Text);

//合并字体信息,图片和字体
byte[] b3 = new byte[headerArray.Length + imageArray.Length + fontByteArray.Length];
Array.Copy(imageArray, b3, imageArray.Length);
Array.Copy(fontByteArray, 0, b3, imageArray.Length, fontByteArray.Length);
Array.Copy(headerArray, 0, b3, fontByteArray.Length + imageArray.Length, headerArray.Length);

//输出图片
//File.WriteAllBytes("C:\\b.jpg", b3);

SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "JPG文件 (*.jpg)|*.jpg"; //保存格式

if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
File.WriteAllBytes(saveFileDialog1.FileName, b3);
}
}

 

2、同步图片

3、从手机读取图片中的文字内容

手机应用中导入字体
        /// <summary>
/// 导入字体
/// </summary>
private void btnImport_Click(object sender, RoutedEventArgs e)
{
PhotoChooserTask photoChooserTask = new PhotoChooserTask();
photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
photoChooserTask.Show();
}
void photoChooserTask_Completed(object sender, PhotoResult e)
{
var stream = e.ChosenPhoto;
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
stream.Seek(0, SeekOrigin.Begin);
if (!SaveFontFile(bytes))
{
MessageBox.Show("导入字体失败,图片文件不符合规定格式!");
}
else
{
MessageBox.Show("导入字体成功!");
}
}

/// <summary>
/// 保存字体文件
/// </summary>
private bool SaveFontFile(byte[] imageArray)
{
try
{
int headLeght = 300;
//截取头文件的二进制流并转换成字符串
if (imageArray.Length < headLeght) return false;
byte[] headerArray = new byte[headLeght];
Array.Copy(imageArray, imageArray.Length - headLeght, headerArray, 0, headLeght);
string headInfo = Encoding.UTF8.GetString(headerArray, 0, headerArray.Length);

//分离头文件信息
string[] items = headInfo.Split(',');
if (items.Length < 6) return false;
string checkChar = items[0].Trim();
if (checkChar != "BeginOOKWriteFonttransfer") return false;
string fontFileName = items[1].Trim();
string fontChineseName = items[2].Trim();
string fontEnglishName = items[3].Trim();
string fontLenght = items[4].Trim();
string fontPicLenght = items[5].Trim();


//截取字体文件的二进制流
Byte[] fontByteArray = new byte[int.Parse(fontLenght)];
Array.Copy(imageArray, int.Parse(fontPicLenght), fontByteArray, 0, fontByteArray.Length);

//写入独立存储
string fileName = string.Format("Fonts\\{0}", fontFileName);
using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!storage.DirectoryExists("Fonts")) storage.CreateDirectory("Fonts");
if (storage.FileExists(fileName)) storage.DeleteFile(fileName);
using (var fileStream = new IsolatedStorageFileStream(fileName, FileMode.Create, storage))
{
using (var writer = new BinaryWriter(fileStream))
{
writer.Write(fontByteArray);
}
}
}
}
catch (Exception exx)
{
MessageBox.Show(exx.ToString());
}
return true;
}

 

      最后 ,感谢《巧用PhotoChooserTask选择器,制作本地TXT阅读器》文章的作者。

posted @ 2012-03-18 15:09  lookrc  阅读(910)  评论(1编辑  收藏  举报