水印可以自己自己制作,也可以用代码写。

我这里主要写如何添加到照片上面。

UWP和WP8.1添加的方法一样。代码是通用的。

UWP和WP8.1没有像WPF和WINFROM中darw这样简便的API可以来用,但是可以提取字节,只好先确定要添加的位置在直接输出字节中了。本来想把思路写在代码后面的。还是写在前面吧。

具体的思路就是像在一个图形中【原图】求出阴影面积【水印】这样方法。

下图 宽800  高400

黑图 高200 宽100

就像这样的图。

大图看作图片,小图看作水印。

图片的像素是四个字节组成的【普通来说】对吧,也就是长宽的字节数分别是,800*4,400*4,这就是长宽的字节数。但是要算全面的总字节数则是 800*400*4=1280 000

这一点多少有些区别。分开算是必须 请不要混了。水印图同样计算。

顺便说一下,字计数是一个一个铺开排列,一行正好是3200个,也就是800*4,总共有1600行,也就是400*4.,但是说3200*1600是总字节那就不对了。

简单来说就是求每一行中水印的宽的所占原图的字节的数量,之后与水印的每一行所占的行数的字节相加。这里面相加的是字节的下标。而是不字节数所表示的数。

也就是求水印占原图的全部的字节的下标。之后将水印的字节按照刚才求得的下标依次输入到原图的字节中就可以了。

左上角来说,水印的左上角占原图的左上角的字节下标就是0,水印的右上角占原图的字节下标就是400.正好就是水印的图的第一行的字节数。 因为是长方形也就是依次向下加就可以了。

难一点的就是左下角和右上角。 我这人也不会说还是具体看代码把。

主要用到的是的API:

WriteableBitmap

BitmapDecoder

这两个,第一个方法用来重画照片。第二个方法用来提取照片的二维数组。

其次,我们要了解照片的像素的。

下面是我们当作水印的照片的

像素数据:

这个照片的像素是200*200*4是总结数据。 200*4是长宽的数据(长宽相等)。也就是像素*4等于字节数据。 像素相乘*4是总数据。  200*4*200*4这样子是错误的。

下面是我们要当作原图的照片。

照片的数据:

总数据:580*410*4. 宽:580*4,高:410*4

OK,我们先提取保存在程序中的照片,并且提取像素数据,以及字节数组

  //打开原图
StorageFile imageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///PB.png", UriKind.Absolute)); IRandomAccessStream accStream = await imageFile.OpenAsync(FileAccessMode.Read);
//打开水印图
StorageFile Mfile=await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///s.jpg", UriKind.Absolute));
//转换流
IRandomAccessStream MiStream= await Mfile.OpenAsync(FileAccessMode.Read);
//使用解码器
BitmapDecoder bd = await BitmapDecoder.CreateAsync(accStream); BitmapDecoder bd_Mi = await BitmapDecoder.CreateAsync(MiStream);
//是否旋转或者缩小
BitmapTransform bt = new BitmapTransform(); ///获取数据
var imageData = await bd.GetPixelDataAsync(BitmapPixelFormat.Bgra8, bd.BitmapAlphaMode, bt, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage);
//获取二维数组
byte[] buffer = imageData.DetachPixelData();
//获取数据
var miData = await bd_Mi.GetPixelDataAsync();
//水印的字节数组
byte[] Mi_buffer = miData.DetachPixelData();

我们先暂且不水印图做任何处理,200*200的叠在原图上面。主要表现如何叠在原图的操作。

我们暂时把水印贴在左上角,右上角等地方。 我们先看确定左上角的代码

需要的数据,以下所有的角落都要用到的

           //原图的高
int Pxh =(int) bd.PixelHeight; //原图的宽
int Pxw = (int)bd.PixelWidth; //原图的高的像素的第一层数据
int Pxh_Byte_H = Pxh * ; //原图的宽的像素的第一层数据
int Pxw_Byte_W = Pxw * ; // 水印的高
int Npxh = (int)bd_Mi.PixelHeight; // 水印的宽
int Npxw = (int)bd_Mi.PixelWidth; // 水印的高的像素的第一层数据
int Npxh_Byte_H = Npxh * ; // 水印的宽的像素的第一层数据
int Npxw_Byte_W = Npxw * ;
//水印的总字节数
int Npx_Byte = Npxh * Npxw * ;
// 水印的像素总数据
int[] Npx_Byte_all = new int[Npx_Byte]; //水印的高的像素总数据
int[] Npx_Byte_all_H = new int[Npxh_Byte_H]; //循环小于水印宽度的数据的计数器
int Times = ; //记录总数据的循环计数器
int ALL_Times = ;

确定左上角的代码:

 {
//获取水印的高的像素的子节点在原图的高的像素的所在的点
for (int i = ; i < Npx_Byte_all_H.Length; i++)
{
Npx_Byte_all_H[i] = (i * Pxw_Byte_W);
}
//获取到水印的高的像素的子节点在原图的高的像素的所在的点之后
//就像计算面积一样,计算水印的所有的点在原图上的点
for (int n = ; n < Npx_Byte_all_H.Length; n++)
{
int nub = Npx_Byte_all_H[n]; Times = ;
//向前推进
//计算每一个点
while (Times < Npxw_Byte_W)
{ if (ALL_Times < Npx_Byte_all.Length)
{
Npx_Byte_all[ALL_Times] = nub + Times; }
Times++;
ALL_Times++;
}
}
//输出到原图上Npx_Byte_all中保存的是水印在原图上所对应的坐标点。
for (int m = ; m < Npx_Byte_all.Length; m++)
{
if (m < Npx_Byte_all.Length - )
{
buffer[Npx_Byte_all[m]] = Mi_buffer[m];
}
} }

确定好位置后,我们就要重绘图片。

   //新建一个原图的WriteableBitmap。长宽和原图一样
WriteableBitmap writBitMap = new WriteableBitmap((int)bd.PixelWidth, (int)bd.PixelHeight);
//利用 writBitMap.PixelBuffer.AsStream()的这个方法向其写入流
using (Stream stream = writBitMap.PixelBuffer.AsStream())
{
await stream.WriteAsync(buffer, , buffer.Length); }
//请求重绘图片
writBitMap.Invalidate(); //输出奥照片上
_iMAGE.Source = writBitMap;

结果就是

嗯...很是不和谐啊... 图片大小问题我们稍后再说,主要说的添加水印不是?

OK,让我们看看右上角的代码

               //获取水印的高的像素的子节点在原图上的子节点
for (int i = ; i < Npx_Byte_all_H.Length; i++)
{
Npx_Byte_all_H[i] = (i * Pxw_Byte_W);
}
//获取水印的高的像素的子节点在原图上的子节点之后,就是计算左上角一样计算,不过这一次是稍稍不同
for (int n = ; n < Npx_Byte_all_H.Length; n++)
{
//获取坐标点
int nub = Npx_Byte_all_H[n];
Times = ;
while (Times < Npxw_Byte_W)
{
if (ALL_Times < Npx_Byte_all.Length && nub > )
{
//确定一行中最小的坐标点,然后加法到水印的宽。
int minNub = nub - Npxw_Byte_W;
Npx_Byte_all[ALL_Times] = minNub + Times;
}
Times++;
ALL_Times++;
}
for (int m = ; m < Npx_Byte_all.Length; m++)
{
if (m < Npx_Byte_all.Length)
{
buffer[Npx_Byte_all[m]] = Mi_buffer[m];
}
}

效果如图

左下角的代码

    ////  水印的最上的左上角的点的坐标
int L_Npxh = (Pxh - Npxh) * Pxw * ;
for (int i = ; i < Npx_Byte_all_H.Length; i++)
{
Npx_Byte_all_H[i] = L_Npxh + (i * Pxw_Byte_W);
}
for (int n = ; n < Npx_Byte_all_H.Length; n++)
{
int nub = Npx_Byte_all_H[n]; Times = ;
while (Times < Npxw_Byte_W)
{
if (ALL_Times < Npx_Byte_all.Length)
{
// int maxNub = nub - Pxw_Byte_W;
Npx_Byte_all[ALL_Times] = nub + Times;
}
ALL_Times++;
Times++;
}
} for (int m = ; m < Npx_Byte_all.Length; m++)
{
if (m < Npx_Byte_all.Length)
{
buffer[Npx_Byte_all[m]] = Mi_buffer[m];
}
}

效果图

右下角的代码

        //水印的左上角在原图上的点
int R_Npxh = (Pxh - Npxh) * Pxw * ;
for(int i=;i<Npx_Byte_all_H.Length;i++)
{
Npx_Byte_all_H[i] = R_Npxh + (i * Pxw_Byte_W);
}
for(int n=;n<Npx_Byte_all_H.Length;n++)
{
int nub = Npx_Byte_all_H[n];
Times = ;
while (Times < Npxw_Byte_W)
{
if(ALL_Times<Npx_Byte_all.Length)
{
int minNub = nub +Pxw_Byte_W- Npxw_Byte_W;
Npx_Byte_all[ALL_Times] = minNub + Times;
}
ALL_Times++;
Times++;
}
}
//输出到原图的字节数组中
for (int m = ; m < Npx_Byte_all.Length; m++)
{
if (m < Npx_Byte_all.Length)
{
buffer[Npx_Byte_all[m]] = Mi_buffer[m];
}
}

效果图

OK,到这里四个角的水印嵌入基本Ok了。

UWP&WP8.1图片照片添加水印的更多相关文章

  1. jQuery图片自动添加水印插件

    JS脚本(jQuery)为图片加水印效果预览:http://hovertree.com/texiao/jquery/94/ 本功能使用HTML5实现,可为图片加上文字水印,可设置文字,设置颜色,位置等 ...

  2. VBA/VBScript提取Word(*.doc)文件中包含的图片(照片)

    VBA/VBScript提取Word(*.doc)文件中包含的图片(照片)   要处理的人事简历表是典型的Word文档,其中一人一份doc,里面包含有个人的照片,如果要把里面的照片复制出来就比较麻烦了 ...

  3. UWP 浏览本地图片及对图片的裁剪

    原文:UWP 浏览本地图片及对图片的裁剪 1.前言 准备给我的校园助手客户端添加一个修改头像的功能,但是查了好多资料都没有找到裁剪图片的简单的方法,最后才找到这个使用Launcher调用系统组件的简单 ...

  4. UWP&WP8.1 重新绘制图片 WriteableBitmap用法 图片转byte[]数组,byte[]数组转图片

    ---恢复内容开始--- WriteableBitmap 是UWP和WP8.1绘制图片的,重组图片的最重要方法.方法较为简单,方法多样性. 通过查看文档,WriteableBitmap的继承性是    ...

  5. UWP&WP8.1 基础控件——Image

    Image是UWP和WP8.1中系统自带的图片展示器. 具有较强的性能,使用也是非常的简单. 使用方式分为在XAML中,在C#代码中. XAML中: 在XAML中使用方式非常简单. 常用XAML So ...

  6. TinyMCE插件:RESPONSIVE filemanager 9 图片自动添加水印

    跟踪function() 搜索(filemanager/upload.php) 在代码中发现,上传成功后,会传回JSON信息数据,于是最后找到方法是 $upload_handler = new Upl ...

  7. TinyMCE插件:Filemanager [4.x-6.x] 图片自动添加水印

    上传图片程序(filemanager/upload.php) 在if (!empty($_FILES) && $upload_files)有一个move_uploaded_file() ...

  8. UWP&WP8.1 基础控件——Grid

    Grid是一个面板控件  Grid是UWP和WPF,WP8.1中最重要的一个控件,相当相当重要. 他是一个面板控件,是用来添加其他控件   但是呢 用法确实简单的很. 大概就这个样子. 你用工具箱拖, ...

  9. UWP&WP8.1 基础控件——Border

    border 是边框控件 border是UWP和WP8.1最常用的控件之一. border字面意义是用来添加边框的. 基础用法 <border BorderThickness="1&q ...

随机推荐

  1. [转载]TSO、UFO、GSO、LRO、GRO和RSS介绍

    TSO.UFO.GSO.LRO.GRO和RSS介绍 ethtool -k < 网络接口>,ethtool --show-offload < 网络接口>,或者可以看到很多网络接口 ...

  2. sql语句中GROUP BY 和 HAVING的使用 count()

    在介绍GROUP BY 和 HAVING 子句前,我们必需先讲讲sql语言中一种特殊的函数:聚合函数, 例如SUM, COUNT, MAX, AVG等.这些函数和其它函数的根本区别就是它们一般作用在多 ...

  3. HDU 1863 畅通工程(Prim,Kruskal,邻接表模板)

    畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  4. AngularJS:模块

    ylbtech-AngularJS:模块 1.返回顶部 1. AngularJS 模块 模块定义了一个应用程序. 模块是应用程序中不同部分的容器. 模块是应用控制器的容器. 控制器通常属于一个模块. ...

  5. The lesser known pitfalls of allowing file uploads on your website

    These days a lot of websites allow users to upload files, but many don’t know about the unknown pitf ...

  6. 深入理解CPU和异构计算芯片GPU/FPGA/ASIC (下篇)

    3.2.1 CPU计算能力分析 这里CPU计算能力用Intel的Haswell架构进行分析,Haswell架构上计算单元有2个FMA(fused multiply-add),每个FMA可以对256bi ...

  7. AJAX——XMLHttpRequest对象的使用

    AJAX是web2.0即动态网页的基础,而XMLHttpRequest对象又是AJAX的核心.XMLHttpRequest对象负责将用户信息以异步通信地发送到服务器端,并接收服务器响应信息和数据 一. ...

  8. C语言学习笔记--内存操作常见错误

    1. 野指针 (1)指针变量中的值是非法的内存地址,进而形成野指针 (2)野指针不是 NULL 指针,是指向不可用内存地址的指针 (3)NULL 指针并无危害,很好判断,也很好调试 (4)C 语言中无 ...

  9. warning: control reaches end of non-void function 和 warning: implicit declaration of function 'rsgClearColor' is invalid in C99

    用gcc编译一个程序的时候出现这样的警告: warning: control reaches end of non-void function 它的意思是:控制到达非void函数的结尾.就是说你的一些 ...

  10. Java开源中文分词类库

      IKAnalyzer  IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包.从2006年12月推出1.0版开始,IKAnalyzer已经推出了3个大版本.最初,它是以开 ...