Quick Retouch+





5.00/5 (7投票s)
这个应用程序将帮助用户快速地在图片上添加不同类型的效果,如素描、旧照片、浮雕、夜视、卡通、油画等。
引言
对于应用创新大赛,我提议开发一个快速润饰+ 应用。
这个应用程序将帮助用户快速地在图片上添加不同类型的效果,如素描、旧照片、浮雕、夜视、卡通、油画等。 用户还可以只用一次触摸就添加不同类型的边框,更改 EXIF 信息,以及调整大小或裁剪图像。 您还可以执行红眼消除,并有一个镜头校正选项。 最后,用户可以使用 Quick Retouch+ 直接将修改后的图像上传到任何社交网络。
背景
如今,润饰图像是一种时尚,社交网络通过图像分享使其更加流行。 除此之外,有时用户需要更改亮度、对比度或大小以使其更时尚。 在这里,我只是将所有东西打包到一个包中,并使其成为一项有趣的任务。 一切皆有可能。
注意
我正在开发这个应用程序是因为我自己的兴趣,现在“Windows 8 Ultra Book App Dev Contest”为我提供了一个展示我的想法和展示我的实力的好机会。 该应用程序的某些部分仍在开发中。
开发步骤
为了使我的开发更容易理解,我将讨论一些代码部分来表示我的详细级别设计 (DLD) 和大多数 UI 活动。
让我们开始旅程吧。
1. APP UI 代码部分
我使用 Expression Studio 来设计我的 UI 的主要模型。 它是 UI 设计的绝佳开发工具。 还有 WPF,它采用基于 XML 的语言 XAML 来定义和链接各种 UI 元素。
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="WPFGui.MainWindow"
Title="MainWindow" Height="687" Width="1010"
Background="Transparent" WindowStyle="None" KeyDown="Window_KeyDown"
BorderThickness="0" AllowsTransparency="True" BorderBrush="#FF73695C">
<Window.Resources>
<!--Border Brush for Select Image-->
<LinearGradientBrush x:Key="SelectionBrush" EndPoint="0.5,1"
MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<LinearGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterY="0.5" CenterX="0.5"/>
<SkewTransform CenterY="0.5" CenterX="0.5"/>
<RotateTransform Angle="-45" CenterY="0.5" CenterX="0.5"/>
<TranslateTransform/>
</TransformGroup>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="#FFC3681E" Offset="0"/>
<GradientStop Color="#FFFBA503" Offset="1"/>
</LinearGradientBrush>
<!---->
<!--Toolbar style-->
<SolidColorBrush x:Key="toolbarMouseOver" Color="White" Opacity=".2"/>
<SolidColorBrush x:Key="toolbarMouseClick" Color="Black" Opacity=".7"/>
<Style x:Key="toolbarButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="buttonBorder" BorderBrush="Transparent"
Margin="0,2,2,2" BorderThickness="1" CornerRadius="1">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="buttonBorder" Property="Background"
Value="{StaticResource ResourceKey=toolbarMouseOver}" />
<Setter TargetName="buttonBorder" Property="BorderBrush"
Value="{StaticResource ResourceKey=toolbarMouseOver}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="buttonBorder" Property="Background"
Value="{StaticResource toolbarMouseClick}" />
<Setter TargetName="buttonBorder" Property="BorderBrush"
Value="{StaticResource toolbarMouseClick}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Static Image Resources-->
<ImageBrush x:Key="Logo" ImageSource="UIRES\kies-png-small.png" />
<!--Style TargetType="{x:Type MenuItem}">
<Setter Property="Background" Value="#FFFFFF"/>
<Setter Property="Foreground" Value="#854E3B"/>
</Style-->
<Style TargetType="{x:Type Control}" x:Key="baseStyle">
<Setter Property="FontFamily" Value="Tahoma"/>
<Setter Property="FontSize" Value="11"/>
</Style>
<!--<Style TargetType="{x:Type Button}" BasedOn="{StaticResource baseStyle}"/>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource baseStyle}"/>
<Style TargetType="{x:Type Menu}" BasedOn="{StaticResource baseStyle}"/>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource baseStyle}"/>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource baseStyle}"/>-->
</Window.Resources>
<Grid>
<Rectangle x:Name="LeftMargin" Margin="0,0,993,16" Fill="#FFCFC7BC"/>
<Rectangle x:Name="RifghtMargin" Margin="0,0,0,16"
Fill="#FFCFC7BC" HorizontalAlignment="Right" Width="6"/>
<Rectangle x:Name="Title" Height="29"
VerticalAlignment="Top"
MouseLeftButtonDown="Title_MouseLeftButtonDown" Fill="#FFCFC7BC"/>
<Rectangle x:Name="Bottom" Height="29"
VerticalAlignment="Bottom"
MouseLeftButtonDown="Title_MouseLeftButtonDown" Fill="#FFCFC7BC"/>
<Rectangle x:Name="Logo" Height="16" VerticalAlignment="Top"
MouseLeftButtonDown="Title_MouseLeftButtonDown"
Fill="{StaticResource ResourceKey=Logo}" Margin="12,5,0,0"
HorizontalAlignment="Left" Width="16" />
<StackPanel Margin="27,0,647,657" Background="Transparent"
Orientation="Horizontal">
<Menu Name="MainMenu" Background="Transparent"
DockPanel.Dock="Left" Margin="5,5,5,-3"
Style="{StaticResource ResourceKey=baseStyle}" Height="27" Width="331.3">
<MenuItem Header="File" Margin="9,0,9,0" Style="{StaticResource StyleMenuItem}">
<MenuItem Header="Add file to Library"/>
<MenuItem Header="Add folder to Library"/>
<Separator/>
<MenuItem Header="Add file to Connected Device" IsEnabled="False"/>
<MenuItem Header="Add Folder to Connected Device" IsEnabled="False"/>
<Separator/>
<MenuItem InputGestureText="Alt+F4" Header="Exit" Click="CloseButton_Click"/>
</MenuItem>
<MenuItem Header="Edit" Margin="9,0,9,0" Style="{StaticResource StyleMenuItem}">
<MenuItem Header="Copy"/>
<MenuItem Header="Pase" IsEnabled="False"/>
<Separator/>
<MenuItem Header="Delete"/>
<Separator/>
<MenuItem Header="Select All"/>
<MenuItem Header="Deselect All"/>
</MenuItem>
<MenuItem Header="View" Margin="9,0,9,0" Style="{StaticResource StyleMenuItem}">
<MenuItem Header="List View"/>
<MenuItem Header="Thumbnail View"/>
<Separator />
<MenuItem Header="Sort Thumbnails" IsEnabled="False"/>
<MenuItem Header="Goto Current playing Music" IsEnabled="False"/>
<MenuItem Header="Goto Current playing Podcast" IsEnabled="False"/>
</MenuItem>
<MenuItem Header="Tool" Margin="9,0,9,0" Style="{StaticResource StyleMenuItem}">
<MenuItem Header="Connect Using Bluetooth"/>
<Separator/>
<MenuItem Header="Emergency Firmware Recovery"/>
<MenuItem Header="Firmware Updgrade Settings"/>
</MenuItem>
<MenuItem Header="Help"
Margin="10,0,9,0" Style="{StaticResource StyleMenuItem}">
<MenuItem Header="Kies Help"/>
<MenuItem Header="Kies Tutorial"/>
<Separator/>
<MenuItem Header="Check for updates"/>
<Separator/>
<MenuItem Header="Kies Information"/>
</MenuItem>
<MenuItem Name="webShareMenu" Header="WebShare"
Margin="10,0,9,0"
Style="{StaticResource StyleMenuItem}" Visibility="Hidden"/>
</Menu>
</StackPanel>
<Border x:Name="Body" Margin="205,29,6,29"
BorderBrush="#FF85817E" MouseUp="Body_MouseUp">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF3C3C3C" Offset="0"/>
<GradientStop Color="#FF2B2B2B" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<Border x:Name="TitleBorder" BorderBrush="#FF73695C"
BorderThickness="1" CornerRadius="0.5">
<StackPanel x:Name="stackPanel1" />
</Border>
<DockPanel LastChildFill="False" VerticalAlignment="Top"
HorizontalAlignment="Right" Margin="0,1.664,0,0">
<Button x:Name="MinimizeButton"
Visibility="Visible"
DockPanel.Dock="Left"
Style="{StaticResource LooklessButton}"
Margin="2" Click="MinimizeButton_Click">
<Image Stretch="Uniform"
Source="UIRES\min-1.png"
Height="10"
Width="10" Margin="3"/>
</Button>
<Button x:Name="MaximizeButton"
Visibility="Visible"
DockPanel.Dock="Left"
Style="{StaticResource LooklessButton}"
Margin="2" Click="MaximizeButton_Click">
<Image Stretch="Uniform"
Source="UIRES\max-1.png"
Height="10"
Width="10" Margin="3"/>
</Button>
<Button x:Name="CloseButton"
Visibility="Visible"
DockPanel.Dock="Left"
Style="{StaticResource LooklessButton}"
Margin="2" Click="CloseButton_Click">
<Image Stretch="Uniform"
Source="UIRES\close-1.png"
Height="10"
Width="10" Margin="3"/>
</Button>
</DockPanel>
<StackPanel x:Name="SideBar" Margin="7,29,766,29" >
<Image Source="UIRes\SideBar.png" Stretch="Fill"
Height="641.384" Margin="0,0,31,0"/>
</StackPanel>
<StackPanel x:Name="RightSide"
Margin="214,30,6,16" Orientation="Vertical">
<Grid>
<Rectangle Height="36"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF747067" Offset="0"/>
<GradientStop Color="#FF5A5750" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Button Content="Add Photos"
Height="28"
HorizontalAlignment="Left" x:Name="button1"
VerticalAlignment="Top" Width="89.5"
Style="{StaticResource ResourceKey=CustomButtonMainInterface}"
Foreground="White"
Margin="4,4,0,0" />
<Button Content="Delete"
Height="28" HorizontalAlignment="Left" x:Name="button1_Copy"
VerticalAlignment="Top"
Width="72.167"
Style="{StaticResource ResourceKey=CustomButtonMainInterface}"
Foreground="#FF929292"
Margin="90.836,4,0,0" IsEnabled="False" />
<Button Content="Transfer To Device"
Height="28" HorizontalAlignment="Left" x:Name="button1_Copy1"
VerticalAlignment="Top" Width="120.5"
Style="{StaticResource ResourceKey=CustomButtonMainInterface}"
Foreground="#FF929292"
Margin="175.667,4,0,0" IsEnabled="False" />
<Button Visibility="Hidden" Content="Edit"
Height="28" HorizontalAlignment="Left" Margin="311,4,0,0"
Name="editButton" Style="{StaticResource CustomButtonMainInterface}"
VerticalAlignment="Top"
Width="63" Click="editButton_Click">
<Button.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF7492EB" Offset="1"/>
<GradientStop Color="#FF4A66BC"/>
</LinearGradientBrush>
</Button.Foreground>
</Button>
</Grid>
<Border>
<Image Source="UIRes\topBar2.png" Stretch="Uniform"/>
</Border>
<Border Height="28" BorderBrush="#FF222222"
BorderThickness="1" HorizontalAlignment="Stretch">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF474747" Offset="0"/>
<GradientStop Color="#FF444444" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<Label Content="2012-2-21" Height="14" x:Name="label1"
Margin="26,0,0,0" Width="52"
Padding="0" HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="White" FontWeight="Light"/>
</Border>
<StackPanel Height="214" x:Name="imagePanel"
Width="Auto" Orientation="Horizontal">
<StackPanel VerticalAlignment="Center"
HorizontalAlignment="Center">
<Border x:Name="imgBorder1"
BorderThickness="1" BorderBrush="Wheat"
Height="104" Margin="20,10"
MouseUp="Border_MouseClick">
<Image Source="UIRes\image1.jpg" />
</Border>
<Border x:Name="imgToolbar1"
BorderThickness="1" BorderBrush="Black"
CornerRadius="1"
Width="102" Height="24"
d:LayoutOverrides="Width,
Height" Visibility="Hidden">
<Border.Effect>
<DropShadowEffect BlurRadius="3" ShadowDepth="2"/>
</Border.Effect>
<Border.Background>
<ImageBrush ImageSource="UIRes\toolbar.png"/>
</Border.Background>
<StackPanel Width="102"
Height="22" Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Button Style="{StaticResource ResourceKey=toolbarButton}"
Margin="2,0">
<Image Source="UIRes\iconStar.png"/>
</Button>
<Path Data="M150,2 L150,22" Margin="0,0.75,0,0.25"
Stretch="Fill"
Width="1" Stroke="#FFB8B8B8"/>
<Button Margin="2,0"
Style="{StaticResource ResourceKey=toolbarButton}"
Width="22" >
<Image Source="UIRes\iconTag.png"/>
</Button>
<Path Data="M150,2 L150,22" Margin="0,0.75,0,0.25"
Stretch="Fill"
Width="1" Stroke="#FFB8B8B8"/>
<Button Margin="2,0"
Style="{StaticResource ResourceKey=toolbarButton}"
Width="22" >
<Image Source="UIRes\iconUndo.png" Margin="0"/>
</Button>
<Path Data="M150,2 L150,22"
Margin="0,0.75,0,0.25"
Stretch="Fill"
Width="1" Stroke="#FFB8B8B8"/>
<Button Margin="2,0"
Style="{StaticResource
ResourceKey=toolbarButton}" Width="22">
<Image Source="UIRes\iconRedo.png"/>
</Button>
</StackPanel>
</Border>
</StackPanel>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Border x:Name="imgBorder2" BorderBrush="Wheat"
BorderThickness="1" Height="93"
Margin="20,10" MouseUp="Border_MouseClick">
<Image Source="UIRes\image2.jpg"/>
</Border>
<Border x:Name="imgToolbar2"
BorderThickness="1" BorderBrush="Black"
CornerRadius="1" Width="102" Height="24"
d:LayoutOverrides="Width, Height" Visibility="Hidden">
<Border.Effect>
<DropShadowEffect BlurRadius="3" ShadowDepth="2"/>
</Border.Effect>
<Border.Background>
<ImageBrush ImageSource="UIRes/toolbar.png"/>
</Border.Background>
<StackPanel Width="102"
Height="22" Orientation="Horizontal"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Style="{StaticResource ResourceKey=toolbarButton}"
Margin="2,0">
<Image Source="UIRes\iconStar.png"/>
</Button>
<Path Data="M150,2 L150,22" Margin="0,0.75,0,0.25"
Stretch="Fill"
Width="1" Stroke="#FFB8B8B8"/>
<Button Margin="2,0"
Style="{StaticResource ResourceKey=toolbarButton}"
Width="22" >
<Image Source="UIRes/iconTag.png"/>
</Button>
<Path Data="M150,2 L150,22" Margin="0,0.75,0,0.25"
Stretch="Fill"
Width="1" Stroke="#FFB8B8B8"/>
<Button Margin="2,0"
Style="{StaticResource ResourceKey=toolbarButton}"
Width="22" >
<Image Source="UIRes/iconUndo.png" Margin="0"/>
</Button>
<Path Data="M150,2 L150,22" Margin="0,0.75,0,0.25"
Stretch="Fill" Width="1" Stroke="#FFB8B8B8"/>
<Button Margin="2,0"
Style="{StaticResource ResourceKey=toolbarButton}"
Width="22">
<Image Source="UIRes/iconRedo.png"/>
</Button>
</StackPanel>
</Border>
</StackPanel>
<StackPanel VerticalAlignment="Center">
<Border x:Name="imgBorder3" BorderBrush="Wheat"
BorderThickness="1" Height="128"
Margin="20,10" MouseUp="Border_MouseClick">
<Image Source="UIRes\image3.jpg"/>
</Border>
<Border x:Name="imgToolbar3" BorderThickness="1"
BorderBrush="Black" CornerRadius="1" Width="102"
Height="24" d:LayoutOverrides="Width,
Height" Visibility="Hidden">
<Border.Effect>
<DropShadowEffect BlurRadius="3" ShadowDepth="2"/>
</Border.Effect>
<Border.Background>
<ImageBrush ImageSource="UIRes/toolbar.png"/>
</Border.Background>
<StackPanel Width="102" Height="22"
Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Button Style="{StaticResource ResourceKey=toolbarButton}"
Margin="2,0">
<Image Source="UIRes\iconStar.png"/>
</Button>
<Path Data="M150,2 L150,22" Margin="0,0.75,0,0.25"
Stretch="Fill"
Width="1" Stroke="#FFB8B8B8"/>
<Button Margin="2,0"
Style="{StaticResource ResourceKey=toolbarButton}"
Width="22" >
<Image Source="UIRes/iconTag.png"/>
</Button>
<Path Data="M150,2 L150,22" Margin="0,0.75,0,0.25"
Stretch="Fill" Width="1" Stroke="#FFB8B8B8"/>
<Button Margin="2,0"
Style="{StaticResource ResourceKey=toolbarButton}"
Width="22" >
<Image Source="UIRes/iconUndo.png" Margin="0"/>
</Button>
<Path Data="M150,2 L150,22" Margin="0,0.75,0,0.25"
Stretch="Fill"
Width="1" Stroke="#FFB8B8B8"/>
<Button Margin="2,0"
Style="{StaticResource ResourceKey=toolbarButton}"
Width="22">
<Image Source="UIRes/iconRedo.png"/>
</Button>
</StackPanel>
</Border>
</StackPanel>
</StackPanel>
</StackPanel>
<Frame x:Name="EditFrame" Content="Frame"
Margin="6,29,6,16" Visibility="Hidden"
NavigationUIVisibility="Hidden" />
</Grid>
</Window>
主要特点
通过屏幕截图,我将在这里描述该应用程序的关键功能。
主界面
关闭左侧和右侧停靠面板时,UI 看起来像这样。
EXIF 信息
调整控制
调整控件可以帮助用户使用滑块更改亮度、对比度、清晰度等。
调整大小和裁剪
用户有两种选择来调整图像大小:按百分比和按像素。 可以手动或根据宽高比进行裁剪。
添加边框
一些可以在图片中添加的预定义边框。
添加效果
目前有十二种效果可用:素描、油画、夜视、卡通、影印、晕影、柔光、简单化妆、海报、帆布、旧照片。 只需触摸任何效果即可在原始图像上获得结果。
镜头校正和红眼消除
最近使用的操作显示在左侧。
网络分享
完成所有工作后,要分享图像,只需选择任何社交网站,提供用户名和密码,然后按登录。 该图像将被上传到您的个人资料。
2. 代码设计
所有类型的模块都由他们自己的处理程序处理,例如效果处理程序处理效果请求。 因此它不会中断其他模块,我们可以根据需要添加更多效果。 我还制作了一个效果 DLL 来提高可用性。
如果我在这里复制和粘贴所有代码,那看起来很奇怪。 我在这里放置了一些代码块来理解设计和代码流。 这是用于添加效果的请求处理程序代码。
private void Effect_Button_Click(object sender, RoutedEventArgs e)
{
Button b = (Button)sender;
ImageEffects effect = new ImageEffects(ref m_unmanagedImg);
AF.UnmanagedImage newImg = null;
//string s = (string)b.Content; // comment by
string s = (string)b.Name; //
switch(s)
{
case "ButtonSketch":
newImg = effect.ApplyEffect(EffectID.Sketch);
break;
case "ButtonPoster":
newImg = effect.ApplyEffect(EffectID.Poster);
break;
case "ButtonNightVision":
newImg = effect.ApplyEffect(EffectID.NightVision);
break;
case "ButtonCartoon":
newImg = effect.ApplyEffect(EffectID.Cartoon);
break;
case "ButtonPhotocopy":
newImg = effect.ApplyEffect(EffectID.Photocopy);
break;
case "ButtonVignetting":
newImg = effect.ApplyEffect(EffectID.Vignetting);
break;
case "ButtonMosaic":
newImg = effect.ApplyEffect(EffectID.Mosaic);
break;
case "ButtonSoftGlow":
newImg = effect.ApplyEffect(EffectID.SoftGlow);
break;
case "ButtonOldImage":
newImg = effect.ApplyEffect(EffectID.OldImage);
break;
case "ButtonOilify":
newImg = effect.ApplyEffect(EffectID.Oilify);
break;
case "ButtonCanvas":
newImg = effect.ApplyEffect(EffectID.Canvas);
break;
case "ButtonEdgeGlow":
newImg = effect.ApplyEffect(EffectID.EdgeGlow);
break;
case "ButtonEmboss":
newImg = effect.ApplyEffect(EffectID.Emboss);
break;
case "ButtonSimpleMakeup":
newImg = effect.ApplyEffect(EffectID.SimpleMakeup);
break;
default:
break;
}
DrawThumb(newImg);
ShowBitmap(newImg);
UpdateHistogram(newImg);
}
现在是 ImageEffects
类代码,它通过 DLL 调用执行活动。 传递输入图像数据,引用输出图像数据,有时还会传递一些参数。 最终效果在输出图像数据中获得并在 UI 中显示。
using System;
using System.Runtime.InteropServices;
namespace WPFGui
{
using AF = AForge.Imaging;
using GDI = System.Drawing;
public enum EffectID
{
Sketch,
Poster,
NightVision,
Cartoon,
Photocopy,
Vignetting,
Mosaic,
SoftGlow,
OldImage,
Oilify,
Canvas,
EdgeGlow,
Emboss,
SimpleMakeup
}
unsafe class ImageEffects : IDisposable
{
#region EffectDLLImport
protected const string dllPath = "Effects.dll";
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 SketchImage
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 ApplyEffectEmbos
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 ApplyOilify
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 OldimageEffect
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 PhotocopyFilter
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 ApplyCanvas
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 NightVision2(ImgInfo* RGBarray);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 NightVision
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 Posterize
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 VignettingFilter
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 Mosaic
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 SimpleMakeUp
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 SoftGlowFilter
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 CartoonFilter
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
[DllImport(dllPath, CallingConvention=CallingConvention.Cdecl)]
unsafe public static extern Int32 EdgeGlow
(ImgInfo* imageIn, ImgInfo* imageOut, float* parameter, int ParamNo);
#endregion
#region Necessary Structures (Unsafe)
[StructLayout(LayoutKind.Sequential)]
unsafe public struct RGBQuad
{
public byte B;
public byte G;
public byte R;
}
[StructLayout(LayoutKind.Sequential)]
unsafe public struct ImgInfo
{
public RGBQuad** rgb;
public byte** gray;
public int height;
public int width;
public int bitdepth;
}
#endregion
#region DATA MEMBERS
public unsafe RGBQuad** rgbInput;
public unsafe RGBQuad** rgbOutput;
public unsafe ImgInfo* nativeInputBitmap;
public unsafe ImgInfo* nativeOutputBitmap;
unsafe byte* inputStream;
unsafe byte* effectOutput;
readonly AF.UnmanagedImage m_inputImage;
AF.UnmanagedImage m_outputImage;
#endregion
unsafe public float* param;
public ImageEffects(ref AF.UnmanagedImage inputBitmap)
{
this.m_inputImage = inputBitmap;
m_outputImage = m_inputImage.Clone();
byte* ptr = (byte*)m_inputImage.ImageData;
int stride = m_inputImage.Stride;
int numBytes = stride * m_inputImage.Height;
inputStream = ptr;
rgbInput = (RGBQuad**)Marshal.AllocHGlobal(sizeof(RGBQuad*) * inputBitmap.Height);
//Output image to be disposed
rgbOutput = (RGBQuad**)Marshal.AllocHGlobal(sizeof(RGBQuad*) * inputBitmap.Height);
effectOutput = (byte*)m_outputImage.ImageData;
//int nextPtr = inputBitmap.Width * 3 + padding;
int nextPtr = stride;
for (int i = 0; i < inputBitmap.Height; i++)
{
*(rgbInput + i) = (RGBQuad*)inputStream;
inputStream += nextPtr;
*(rgbOutput + i) = (RGBQuad*)effectOutput;
effectOutput += nextPtr;
}
inputStream = ptr;
nativeInputBitmap = (ImgInfo*)Marshal.AllocHGlobal(sizeof(ImgInfo));
nativeOutputBitmap = (ImgInfo*)Marshal.AllocHGlobal(sizeof(ImgInfo));
nativeInputBitmap->width = nativeOutputBitmap->width = inputBitmap.Width;
nativeInputBitmap->height = nativeOutputBitmap->height = inputBitmap.Height;
nativeInputBitmap->bitdepth = nativeOutputBitmap->bitdepth = 24;
nativeInputBitmap->rgb = rgbInput;
nativeOutputBitmap->rgb = rgbOutput;
nativeInputBitmap->gray = null;
nativeOutputBitmap->gray = null;
}
~ImageEffects()
{
Dispose();
}
public void Dispose()
{
if (rgbInput != null)
{
Marshal.FreeHGlobal((IntPtr)rgbInput);
rgbInput = null;
}
if (rgbOutput != null)
{
Marshal.FreeHGlobal((IntPtr)rgbOutput);
rgbOutput = null;
}
//if (effectOutput != null)
//{
// Marshal.FreeHGlobal((IntPtr)effectOutput);
// effectOutput = null;
//}
if (nativeInputBitmap != null)
{
Marshal.FreeHGlobal((IntPtr)nativeInputBitmap);
nativeInputBitmap = null;
}
if (nativeOutputBitmap != null)
{
Marshal.FreeHGlobal((IntPtr)nativeOutputBitmap);
nativeOutputBitmap = null;
}
inputStream = null;
effectOutput = null;
}
#if !DISABLE
public AF.UnmanagedImage ApplyEffect(EffectID effectId)
{
int paramNo;
switch (effectId)
{
case EffectID.Sketch:
{
//--------- SKETCH IMAGE EFFECT _------------------------------
paramNo = 1;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 16;
SketchImage(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.Poster:
{
//--------- Posterize && --------- ---------------------
paramNo = 1;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 128;
Posterize(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.NightVision:
{
//NightVision--- image Effect--
paramNo = 1;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
//param = (float*)Marshal.AllocHGlobal(sizeof(float) * 6);
param[0] = 200;
//NightVision2(nativeInputBitmap);
NightVision(nativeInputBitmap, nativeOutputBitmap, param, 1);
break;
}
case EffectID.Cartoon:
{
// -------------- cartoon --------- --------------------------------
paramNo = 2;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 8.0f;
param[1] = 0.3f;
CartoonFilter(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.Photocopy:
{
//--------------- Photocopy---- -------------------------
paramNo = 2;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 25;
param[1] = 0.85f;
PhotocopyFilter(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.Vignetting:
{
////--------------- vignetting---- -------------------------
paramNo = 1;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 1.2f;
VignettingFilter(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.Mosaic:
{
////--------------- Mosaic--- -------------------------
paramNo = 3;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 15;
param[1] = 200; // range 0.0 to 1.0, increment 0.2
param[2] = 4;
Mosaic(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.SoftGlow:
{
////--------Softglow ----
paramNo = 1;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 5;
SoftGlowFilter(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.OldImage:
{
////------------ OLD image---------------------- ------------
paramNo = 1;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 0.2f;
OldimageEffect(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.Oilify:
{
paramNo = 2;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 10;
param[1] = 10;
ApplyOilify(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.Canvas:
{
paramNo = 3;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 2;
param[1] = 1;
param[2] = 1;
ApplyCanvas(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.EdgeGlow:
{
////-----Edgeglow
paramNo = 3;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 11;
param[1] = 11;
param[2] = 1;
EdgeGlow(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.Emboss:
{
////-----Emboss
paramNo = 0;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
ApplyEffectEmbos(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
case EffectID.SimpleMakeup:
{
paramNo = 2;
param = (float*)Marshal.AllocHGlobal(sizeof(float) * (paramNo));
param[0] = 4;
param[1] = 45;
SimpleMakeUp(nativeInputBitmap, nativeOutputBitmap, param, paramNo);
break;
}
default:
System.Windows.MessageBox.Show("Done Nothing");
break;
}
Marshal.FreeHGlobal((IntPtr)param);
param = null;
return m_outputImage;
}
#endif
}
}
同样,要添加边框,请使用边框处理程序
private void Frame_Button_Click(object sender, RoutedEventArgs e)
{
string buttonName = (string)((Button)sender).Name;
string fileName = @"Frames\" + buttonName + ".png";
AF.UnmanagedImage frameImage = null;
DisposableGDIBitmap frameBMP = new DisposableGDIBitmap(fileName);
try
{
//New Instance of Unmanaged bitmap
frameImage = new AF.UnmanagedImage(frameBMP.GetBitmapData);
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.ToString());
}
AF.UnmanagedImage viewImg = this.m_frames.getFramedImage(frameImage, m_unmanagedImg);
DrawThumb(viewImg);
ShowBitmap(viewImg);
UpdateHistogram(viewImg);
}
此类负责将边框添加到图像
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WPFGui
{
using AF = AForge.Imaging;
using GDI = System.Drawing;
class ImageFrame
{
AF.UnmanagedImage resizedFrame;
AF.UnmanagedImage originalFrame;
AF.UnmanagedImage resultImage;
AF.Filters.ResizeBilinear resizeBilinearFilter;
GDI.Color framePixelColor;
AF.Filters.RotateBilinear rotateBilinearFilter;
private int RED = 240;
private int GREEN = 240;
private int BLUE = 240;
private float frameRatio;
private float mainImageRatio;
public ImageFrame()
{
}
public AF.UnmanagedImage getFramedImage
(AF.UnmanagedImage frameUnmImg, AF.UnmanagedImage mainImageUnmImg)
{
this.resultImage = mainImageUnmImg.Clone();
this.frameRatio = (float)frameUnmImg.Width / (float)frameUnmImg.Height;
this.mainImageRatio =
(float)this.resultImage.Width / (float)this.resultImage.Height;
if (!((this.frameRatio <= 1.0 && this.mainImageRatio <= 1.0) ||
(1.0 <= this.frameRatio && 1.0 <= this.mainImageRatio)))
{
this.rotateBilinearFilter = new AF.Filters.RotateBilinear(90, false);
this.originalFrame = this.rotateBilinearFilter.Apply(frameUnmImg);
}
else
{
this.originalFrame = frameUnmImg.Clone();
}
this.resizeBilinearFilter =
new AF.Filters.ResizeBilinear(this.resultImage.Width, this.resultImage.Height);
this.resizedFrame = this.resizeBilinearFilter.Apply(originalFrame);
try
{
for (int h = 0; h < this.resultImage.Height; h++)
{
for (int w = 0; w < this.resultImage.Width; w++)
{
this.framePixelColor = this.resizedFrame.GetPixel(w, h);
if (!((0 == this.framePixelColor.A) || (this.framePixelColor.R >
this.RED && this.framePixelColor.G >
this.GREEN && this.framePixelColor.B > this.BLUE)))
{
this.resultImage.SetPixel(w, h, this.framePixelColor);
}
}
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.ToString());
}
return this.resultImage;
}
}
}
webshare 处理程序处理所有类型的图像上传请求
private void LoginToWebshare(object sender, RoutedEventArgs e)
{
string userName = UserNameBox.Text;
string userPassword = UserPasswordBox.Password;
System.Windows.MessageBox.Show(userName);
Button b = (Button)sender;
if (m_unmanagedImg == null)
return;
// LoginToSocialNetwork(userName,userPassword,networkName);
}
应用程序中使用的超级本功能
用于控制活动、滑块、放大/缩小和图像切换的滑动和触摸功能。