Merge pull request #43 from rukmanig/rukmanig-image
Add sample code to process images using U-SQL
This commit is contained in:
Коммит
01d91b3944
|
@ -0,0 +1,48 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{182E2583-ECAD-465B-BB50-91101D7C24CE}") = "ImageApp", "ImageApp\ImageApp.usqlproj", "{B31F4C0B-0586-48C1-B260-E97172E3B2C1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Images", "Images\Images.csproj", "{97595649-6032-45EE-87D6-F780C0FE4A51}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|x64.Build.0 = Debug|x64
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|x86.Build.0 = Debug|x86
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|x64.ActiveCfg = Release|x64
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|x64.Build.0 = Release|x64
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|x86.ActiveCfg = Release|x86
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|x86.Build.0 = Release|x86
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|x64.Build.0 = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>ebf674ed-12ad-425a-b70d-8e482046d2a1</ProjectGuid>
|
||||
<OutputType>File</OutputType>
|
||||
<AssemblyName>Algebra.xml</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<Name>Image</Name>
|
||||
<RootNamespace>Image</RootNamespace>
|
||||
<RuntimeVersion>default</RuntimeVersion>
|
||||
<OutputStreamPath>C:\Users\rukmanig\AppData\Local\USQLDataRoot</OutputStreamPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Script Include="Script.usql" />
|
||||
<ScriptCode Include="Script.usql.cs">
|
||||
<DependentUpon>Script.usql</DependentUpon>
|
||||
</ScriptCode>
|
||||
</ItemGroup>
|
||||
<Import Project="$(AppData)\Microsoft\DataLake\MsBuild\1.0\Usql.targets" />
|
||||
<PropertyGroup>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
using Microsoft.Analytics.Interfaces;
|
||||
using Microsoft.Analytics.Types.Sql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Image
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{182E2583-ECAD-465B-BB50-91101D7C24CE}") = "ImageApp", "ImageApp\ImageApp.usqlproj", "{B31F4C0B-0586-48C1-B260-E97172E3B2C1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Images", "Images\Images.csproj", "{97595649-6032-45EE-87D6-F780C0FE4A51}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|x64.Build.0 = Debug|x64
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Debug|x86.Build.0 = Debug|x86
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|x64.ActiveCfg = Release|x64
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|x64.Build.0 = Release|x64
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|x86.ActiveCfg = Release|x86
|
||||
{B31F4C0B-0586-48C1-B260-E97172E3B2C1}.Release|x86.Build.0 = Release|x86
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|x64.Build.0 = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{97595649-6032-45EE-87D6-F780C0FE4A51}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>b31f4c0b-0586-48c1-b260-e97172e3b2c1</ProjectGuid>
|
||||
<OutputType>File</OutputType>
|
||||
<AssemblyName>Algebra.xml</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<Name>ImageApp</Name>
|
||||
<RootNamespace>ImageApp</RootNamespace>
|
||||
<RuntimeVersion>default</RuntimeVersion>
|
||||
<OutputStreamPath>C:\Users\rukmanig\AppData\Local\USQLDataRoot</OutputStreamPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Script Include="ImageFunctions.usql">
|
||||
<UseLocalComputeAccount>true</UseLocalComputeAccount>
|
||||
<LocalComputeAccount>localcomputeaccount</LocalComputeAccount>
|
||||
<LocalDatabase>master</LocalDatabase>
|
||||
<LocalSchema>dbo</LocalSchema>
|
||||
<ClusterComputeAccount>sandbox</ClusterComputeAccount>
|
||||
<ClusterDatabase>master</ClusterDatabase>
|
||||
<ClusterSchema>dbo</ClusterSchema>
|
||||
</Script>
|
||||
<ScriptCode Include="ImageFunctions.usql.cs">
|
||||
<DependentUpon>ImageFunctions.usql</DependentUpon>
|
||||
</ScriptCode>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Drawing">
|
||||
<Name>System.Drawing</Name>
|
||||
<AssemblyName>System.Drawing.dll</AssemblyName>
|
||||
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\r1p4lg3j.wxa\System.Drawing.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(AppData)\Microsoft\DataLake\MsBuild\1.0\Usql.targets" />
|
||||
<PropertyGroup>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>b31f4c0b-0586-48c1-b260-e97172e3b2c1</ProjectGuid>
|
||||
<OutputType>File</OutputType>
|
||||
<AssemblyName>Algebra.xml</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<Name>ImageApp</Name>
|
||||
<RootNamespace>ImageApp</RootNamespace>
|
||||
<RuntimeVersion>default</RuntimeVersion>
|
||||
<OutputStreamPath>C:\Users\rukmanig\AppData\Local\USQLDataRoot</OutputStreamPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Script Include="ImageFunctions.usql">
|
||||
<UseLocalComputeAccount>true</UseLocalComputeAccount>
|
||||
<LocalComputeAccount>localcomputeaccount</LocalComputeAccount>
|
||||
<LocalDatabase>master</LocalDatabase>
|
||||
<LocalSchema>dbo</LocalSchema>
|
||||
</Script>
|
||||
<Script Include="ImageLoaderADLS.usql">
|
||||
<UseLocalComputeAccount>true</UseLocalComputeAccount>
|
||||
<LocalComputeAccount>localcomputeaccount</LocalComputeAccount>
|
||||
<LocalDatabase>master</LocalDatabase>
|
||||
<LocalSchema>dbo</LocalSchema>
|
||||
<ClusterComputeAccount>sandbox</ClusterComputeAccount>
|
||||
<ClusterDatabase>master</ClusterDatabase>
|
||||
<ClusterSchema>dbo</ClusterSchema>
|
||||
</Script>
|
||||
<Script Include="ImageProcessor.usql">
|
||||
<UseLocalComputeAccount>true</UseLocalComputeAccount>
|
||||
<LocalComputeAccount>localcomputeaccount</LocalComputeAccount>
|
||||
<LocalDatabase>master</LocalDatabase>
|
||||
<LocalSchema>dbo</LocalSchema>
|
||||
</Script>
|
||||
<Script Include="ImageQuery.usql">
|
||||
<UseLocalComputeAccount>true</UseLocalComputeAccount>
|
||||
<LocalComputeAccount>localcomputeaccount</LocalComputeAccount>
|
||||
<LocalDatabase>master</LocalDatabase>
|
||||
<LocalSchema>dbo</LocalSchema>
|
||||
</Script>
|
||||
<ScriptCode Include="ImageFunctions.usql.cs">
|
||||
<DependentUpon>ImageFunctions.usql</DependentUpon>
|
||||
</ScriptCode>
|
||||
<ScriptCode Include="ImageLoaderADLS.usql.cs">
|
||||
<DependentUpon>ImageLoaderADLS.usql</DependentUpon>
|
||||
</ScriptCode>
|
||||
<ScriptCode Include="ImageProcessor.usql.cs">
|
||||
<DependentUpon>ImageProcessor.usql</DependentUpon>
|
||||
</ScriptCode>
|
||||
<ScriptCode Include="ImageQuery.usql.cs">
|
||||
<DependentUpon>ImageQuery.usql</DependentUpon>
|
||||
</ScriptCode>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Drawing">
|
||||
<Name>System.Drawing</Name>
|
||||
<AssemblyName>System.Drawing.dll</AssemblyName>
|
||||
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\r1p4lg3j.wxa\System.Drawing.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(AppData)\Microsoft\DataLake\MsBuild\1.0\Usql.targets" />
|
||||
<PropertyGroup>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,31 @@
|
|||
CREATE ASSEMBLY IF NOT EXISTS Images
|
||||
FROM @"/rukmanig/assemblies/Images.dll";
|
||||
|
||||
REFERENCE ASSEMBLY Images;
|
||||
|
||||
@image_data =
|
||||
EXTRACT image_data byte[]
|
||||
FROM @"/rukmanig/images/guard.jpg"
|
||||
USING new Images.ImageExtractor();
|
||||
|
||||
@image_properties =
|
||||
SELECT Images.ImageOps.getImageProperty(image_data, 0x8298) AS image_copyright,
|
||||
Images.ImageOps.getImageProperty(image_data, 0x010F) AS image_equipment_make,
|
||||
Images.ImageOps.getImageProperty(image_data, 0x0110) AS image_equipment_model,
|
||||
Images.ImageOps.getImageProperty(image_data, 0x010E) AS image_description
|
||||
FROM @image_data;
|
||||
|
||||
OUTPUT @image_properties
|
||||
TO @"/rukmanig/output/images/imageproperties.csv"
|
||||
USING Outputters.Csv();
|
||||
|
||||
@scaled_image =
|
||||
SELECT Images.ImageOps.scaleImageTo(image_data, 150, 150) AS thumbnail_image
|
||||
FROM @image_data;
|
||||
|
||||
OUTPUT @scaled_image
|
||||
TO "/rukmanig/output/images/guard_thumbnail.jpg"
|
||||
USING new Images.ImageOutputter();
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
using Microsoft.Analytics.Interfaces;
|
||||
using Microsoft.Analytics.Types.Sql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace ImageApp
|
||||
{
|
||||
// Helper class that binds together a stream and an image so that they can be disposed together.
|
||||
// It is needed because the stream must stay open for as long as the image is being used.
|
||||
class StreamImage : IDisposable
|
||||
{
|
||||
private MemoryStream mMemoryStream;
|
||||
public Image mImage;
|
||||
|
||||
public StreamImage(byte[] inBytes)
|
||||
{
|
||||
mMemoryStream = new MemoryStream(inBytes);
|
||||
mImage = null;
|
||||
try
|
||||
{
|
||||
mImage = Image.FromStream(mMemoryStream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (mImage == null)
|
||||
{
|
||||
mMemoryStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
mImage.Dispose();
|
||||
}
|
||||
finally
|
||||
{
|
||||
mMemoryStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sample image utilities and operations.
|
||||
public class ImageOps
|
||||
{
|
||||
// The quality setting for generated JPEG files.
|
||||
private const long JPEG_QUALITY = 90;
|
||||
|
||||
// Utility: convert a byte array into an image.
|
||||
private static StreamImage byteArrayToImage(byte[] inBytes)
|
||||
{
|
||||
return new StreamImage(inBytes);
|
||||
}
|
||||
|
||||
// Utility: convert an image into a byte array containing a JPEG encoding of the image.
|
||||
private static byte[] imageToByteArray(Image inImage)
|
||||
{
|
||||
using (MemoryStream outStream = new MemoryStream())
|
||||
{
|
||||
ImageCodecInfo jpegCodec = null;
|
||||
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
|
||||
{
|
||||
if (codec.FormatID == ImageFormat.Jpeg.Guid)
|
||||
{
|
||||
jpegCodec = codec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jpegCodec == null)
|
||||
{
|
||||
throw new MissingMemberException("Cannot find JPEG encoder");
|
||||
}
|
||||
using (EncoderParameters ep = new EncoderParameters(1))
|
||||
{
|
||||
using (EncoderParameter p = new EncoderParameter(Encoder.Quality, JPEG_QUALITY))
|
||||
{
|
||||
ep.Param[0] = p;
|
||||
inImage.Save(outStream, jpegCodec, ep);
|
||||
return outStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Utility: draw the input image to the output image within the given region (at high quality).
|
||||
private static void drawImage(Image inImage, Bitmap outImage, Rectangle region)
|
||||
{
|
||||
outImage.SetResolution(inImage.HorizontalResolution, inImage.VerticalResolution);
|
||||
using (Graphics g = Graphics.FromImage(outImage))
|
||||
{
|
||||
// Clear background pixels, if any will remain after the drawing below.
|
||||
if ((region.X != 0) ||
|
||||
(region.Y != 0) ||
|
||||
(region.Height != outImage.Height) ||
|
||||
(region.Width != outImage.Width))
|
||||
{
|
||||
g.Clear(Color.Black);
|
||||
}
|
||||
// Draw image at high quality.
|
||||
g.CompositingMode = CompositingMode.SourceCopy;
|
||||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
using (ImageAttributes attributes = new ImageAttributes())
|
||||
{
|
||||
attributes.SetWrapMode(WrapMode.TileFlipXY);
|
||||
g.DrawImage(inImage, region, 0, 0, inImage.Width, inImage.Height, GraphicsUnit.Pixel, attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: return the value of an image property (provided it's a string or integer).
|
||||
// Use property ID 8298 for copyright.
|
||||
// See https://msdn.microsoft.com/en-us/library/ms534416.aspx for additional IDs.
|
||||
public static string getImageProperty(byte[] inBytes, int propertyId)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
foreach (PropertyItem propItem in inImage.mImage.PropertyItems)
|
||||
{
|
||||
if (propItem.Id == propertyId)
|
||||
{
|
||||
return (propItem.Type == 2) ? System.Text.Encoding.UTF8.GetString(propItem.Value) : propItem.Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Operation: rotate an image by 90, 180, or 270 degrees.
|
||||
public static byte[] rotateImage(byte[] inBytes, int rotateType)
|
||||
{
|
||||
RotateFlipType rotateFlipType;
|
||||
switch (rotateType)
|
||||
{
|
||||
case 1:
|
||||
rotateFlipType = RotateFlipType.Rotate90FlipNone;
|
||||
break;
|
||||
case 2:
|
||||
rotateFlipType = RotateFlipType.Rotate180FlipNone;
|
||||
break;
|
||||
case 3:
|
||||
rotateFlipType = RotateFlipType.Rotate270FlipNone;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Invalid type");
|
||||
}
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
inImage.mImage.RotateFlip(rotateFlipType);
|
||||
return imageToByteArray(inImage.mImage);
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: scale an image by a scale factor.
|
||||
public static byte[] scaleImageBy(byte[] inBytes, float scaleFactor)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
int outWidth = (int)(inImage.mImage.Width * scaleFactor);
|
||||
int outHeight = (int)(inImage.mImage.Height * scaleFactor);
|
||||
using (Bitmap outImage = new Bitmap(outWidth, outHeight))
|
||||
{
|
||||
drawImage(inImage.mImage, outImage, new Rectangle(0, 0, outWidth, outHeight));
|
||||
return imageToByteArray(outImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: scale an image to the given dimensions.
|
||||
public static byte[] scaleImageTo(byte[] inBytes, int outWidth, int outHeight)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
int x, y, w, h;
|
||||
int iWoH = inImage.mImage.Width * outHeight;
|
||||
int iHoW = inImage.mImage.Height * outWidth;
|
||||
if (iWoH < iHoW)
|
||||
{
|
||||
w = (int)((double)(iWoH) / inImage.mImage.Height);
|
||||
h = outHeight;
|
||||
x = (int)((outWidth - w) / 2.0);
|
||||
y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = outWidth;
|
||||
h = (int)((double)(iHoW) / inImage.mImage.Width);
|
||||
x = 0;
|
||||
y = (int)((outHeight - h) / 2.0);
|
||||
}
|
||||
using (Bitmap outImage = new Bitmap(outWidth, outHeight))
|
||||
{
|
||||
drawImage(inImage.mImage, outImage, new Rectangle(x, y, w, h));
|
||||
return imageToByteArray(outImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] GetByteArrayforImage(Stream input)
|
||||
{
|
||||
try
|
||||
{
|
||||
//var fullFileName = "C:\\Users\\rukmanig\\AppData\\Local\\USQLDataRoot\\images\\" + category + "\\" + filename + ".tiff";
|
||||
/* var fullFileName = @"/rukmanig/images/" + filename + ".tiff";
|
||||
string[] jpgFileName = ConvertTiffToJpeg(fullFileName);*/
|
||||
//var fullFileName = "\\images\\" + category + "\\" + filename + ".tiff";
|
||||
|
||||
var image = Image.FromStream(input);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
||||
return ms.ToArray();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] ConvertTiffToJpeg(string fileName)
|
||||
{
|
||||
using (Image imageFile = Image.FromFile(fileName))
|
||||
{
|
||||
FrameDimension frameDimensions = new FrameDimension(
|
||||
imageFile.FrameDimensionsList[0]);
|
||||
|
||||
// Gets the number of pages from the tiff image (if multipage)
|
||||
int frameNum = imageFile.GetFrameCount(frameDimensions);
|
||||
string[] jpegPaths = new string[frameNum];
|
||||
|
||||
for (int frame = 0; frame < frameNum; frame++)
|
||||
{
|
||||
// Selects one frame at a time and save as jpeg.
|
||||
imageFile.SelectActiveFrame(frameDimensions, frame);
|
||||
using (Bitmap bmp = new Bitmap(imageFile))
|
||||
{
|
||||
jpegPaths[frame] = String.Format("{0}\\{1}{2}.jpg",
|
||||
Path.GetDirectoryName(fileName),
|
||||
Path.GetFileNameWithoutExtension(fileName),
|
||||
frame);
|
||||
bmp.Save(jpegPaths[frame], ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
|
||||
return jpegPaths;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
|
||||
public class ImageExtractor : IExtractor
|
||||
{
|
||||
|
||||
public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
|
||||
{
|
||||
byte[] imageArray = ImageOps.GetByteArrayforImage(input.BaseStream);
|
||||
output.Set<byte[]>(0, imageArray);
|
||||
yield return output.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
|
||||
public class ImageOutputter : IOutputter
|
||||
{
|
||||
public override void Output(IRow input, IUnstructuredWriter output)
|
||||
{
|
||||
var obj = input.Get<object>(0);
|
||||
byte[] imageArray = (byte[])obj;
|
||||
using (MemoryStream ms = new MemoryStream(imageArray))
|
||||
{
|
||||
var image = Image.FromStream(ms);
|
||||
image.Save(output.BaseStream, ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
CREATE ASSEMBLY IF NOT EXISTS Images
|
||||
FROM @"/rukmanig/assemblies/Images.dll";
|
||||
|
||||
REFERENCE ASSEMBLY Images;
|
||||
|
||||
@image_data =
|
||||
EXTRACT image_data byte[]
|
||||
FROM @"/rukmanig/images/guard.jpg"
|
||||
USING new Images.ImageExtractor();
|
||||
|
||||
@image_properties =
|
||||
SELECT Images.ImageOps.getImageProperty(image_data, 0x8298) AS image_copyright,
|
||||
Images.ImageOps.getImageProperty(image_data, 0x010F) AS image_equipment_make,
|
||||
Images.ImageOps.getImageProperty(image_data, 0x0110) AS image_equipment_model,
|
||||
Images.ImageOps.getImageProperty(image_data, 0x010E) AS image_description
|
||||
FROM @image_data;
|
||||
|
||||
OUTPUT @image_properties
|
||||
TO @"/rukmanig/output/images/imageproperties.csv"
|
||||
USING Outputters.Csv();
|
||||
|
||||
@scaled_image =
|
||||
SELECT Images.ImageOps.scaleImageTo(image_data, 150, 150) AS thumbnail_image
|
||||
FROM @image_data;
|
||||
|
||||
OUTPUT @scaled_image
|
||||
TO "/rukmanig/output/images/guard_thumbnail.jpg"
|
||||
USING new Images.ImageOutputter();
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
using Microsoft.Analytics.Interfaces;
|
||||
using Microsoft.Analytics.Types.Sql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace ImageApp
|
||||
{
|
||||
// Helper class that binds together a stream and an image so that they can be disposed together.
|
||||
// It is needed because the stream must stay open for as long as the image is being used.
|
||||
class StreamImage : IDisposable
|
||||
{
|
||||
private MemoryStream mMemoryStream;
|
||||
public Image mImage;
|
||||
|
||||
public StreamImage(byte[] inBytes)
|
||||
{
|
||||
mMemoryStream = new MemoryStream(inBytes);
|
||||
mImage = null;
|
||||
try
|
||||
{
|
||||
mImage = Image.FromStream(mMemoryStream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (mImage == null)
|
||||
{
|
||||
mMemoryStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
mImage.Dispose();
|
||||
}
|
||||
finally
|
||||
{
|
||||
mMemoryStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sample image utilities and operations.
|
||||
public class ImageOps
|
||||
{
|
||||
// The quality setting for generated JPEG files.
|
||||
private const long JPEG_QUALITY = 90;
|
||||
|
||||
// Utility: convert a byte array into an image.
|
||||
private static StreamImage byteArrayToImage(byte[] inBytes)
|
||||
{
|
||||
return new StreamImage(inBytes);
|
||||
}
|
||||
|
||||
// Utility: convert an image into a byte array containing a JPEG encoding of the image.
|
||||
private static byte[] imageToByteArray(Image inImage)
|
||||
{
|
||||
using (MemoryStream outStream = new MemoryStream())
|
||||
{
|
||||
ImageCodecInfo jpegCodec = null;
|
||||
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
|
||||
{
|
||||
if (codec.FormatID == ImageFormat.Jpeg.Guid)
|
||||
{
|
||||
jpegCodec = codec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jpegCodec == null)
|
||||
{
|
||||
throw new MissingMemberException("Cannot find JPEG encoder");
|
||||
}
|
||||
using (EncoderParameters ep = new EncoderParameters(1))
|
||||
{
|
||||
using (EncoderParameter p = new EncoderParameter(Encoder.Quality, JPEG_QUALITY))
|
||||
{
|
||||
ep.Param[0] = p;
|
||||
inImage.Save(outStream, jpegCodec, ep);
|
||||
return outStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Utility: draw the input image to the output image within the given region (at high quality).
|
||||
private static void drawImage(Image inImage, Bitmap outImage, Rectangle region)
|
||||
{
|
||||
outImage.SetResolution(inImage.HorizontalResolution, inImage.VerticalResolution);
|
||||
using (Graphics g = Graphics.FromImage(outImage))
|
||||
{
|
||||
// Clear background pixels, if any will remain after the drawing below.
|
||||
if ((region.X != 0) ||
|
||||
(region.Y != 0) ||
|
||||
(region.Height != outImage.Height) ||
|
||||
(region.Width != outImage.Width))
|
||||
{
|
||||
g.Clear(Color.Black);
|
||||
}
|
||||
// Draw image at high quality.
|
||||
g.CompositingMode = CompositingMode.SourceCopy;
|
||||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
using (ImageAttributes attributes = new ImageAttributes())
|
||||
{
|
||||
attributes.SetWrapMode(WrapMode.TileFlipXY);
|
||||
g.DrawImage(inImage, region, 0, 0, inImage.Width, inImage.Height, GraphicsUnit.Pixel, attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: return the value of an image property (provided it's a string or integer).
|
||||
// Use property ID 8298 for copyright.
|
||||
// See https://msdn.microsoft.com/en-us/library/ms534416.aspx for additional IDs.
|
||||
public static string getImageProperty(byte[] inBytes, int propertyId)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
foreach (PropertyItem propItem in inImage.mImage.PropertyItems)
|
||||
{
|
||||
if (propItem.Id == propertyId)
|
||||
{
|
||||
return (propItem.Type == 2) ? System.Text.Encoding.UTF8.GetString(propItem.Value) : propItem.Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Operation: rotate an image by 90, 180, or 270 degrees.
|
||||
public static byte[] rotateImage(byte[] inBytes, int rotateType)
|
||||
{
|
||||
RotateFlipType rotateFlipType;
|
||||
switch (rotateType)
|
||||
{
|
||||
case 1:
|
||||
rotateFlipType = RotateFlipType.Rotate90FlipNone;
|
||||
break;
|
||||
case 2:
|
||||
rotateFlipType = RotateFlipType.Rotate180FlipNone;
|
||||
break;
|
||||
case 3:
|
||||
rotateFlipType = RotateFlipType.Rotate270FlipNone;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Invalid type");
|
||||
}
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
inImage.mImage.RotateFlip(rotateFlipType);
|
||||
return imageToByteArray(inImage.mImage);
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: scale an image by a scale factor.
|
||||
public static byte[] scaleImageBy(byte[] inBytes, float scaleFactor)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
int outWidth = (int)(inImage.mImage.Width * scaleFactor);
|
||||
int outHeight = (int)(inImage.mImage.Height * scaleFactor);
|
||||
using (Bitmap outImage = new Bitmap(outWidth, outHeight))
|
||||
{
|
||||
drawImage(inImage.mImage, outImage, new Rectangle(0, 0, outWidth, outHeight));
|
||||
return imageToByteArray(outImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: scale an image to the given dimensions.
|
||||
public static byte[] scaleImageTo(byte[] inBytes, int outWidth, int outHeight)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
int x, y, w, h;
|
||||
int iWoH = inImage.mImage.Width * outHeight;
|
||||
int iHoW = inImage.mImage.Height * outWidth;
|
||||
if (iWoH < iHoW)
|
||||
{
|
||||
w = (int)((double)(iWoH) / inImage.mImage.Height);
|
||||
h = outHeight;
|
||||
x = (int)((outWidth - w) / 2.0);
|
||||
y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = outWidth;
|
||||
h = (int)((double)(iHoW) / inImage.mImage.Width);
|
||||
x = 0;
|
||||
y = (int)((outHeight - h) / 2.0);
|
||||
}
|
||||
using (Bitmap outImage = new Bitmap(outWidth, outHeight))
|
||||
{
|
||||
drawImage(inImage.mImage, outImage, new Rectangle(x, y, w, h));
|
||||
return imageToByteArray(outImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] GetByteArrayforImage(Stream input)
|
||||
{
|
||||
try
|
||||
{
|
||||
//var fullFileName = "C:\\Users\\rukmanig\\AppData\\Local\\USQLDataRoot\\images\\" + category + "\\" + filename + ".tiff";
|
||||
/* var fullFileName = @"/rukmanig/images/" + filename + ".tiff";
|
||||
string[] jpgFileName = ConvertTiffToJpeg(fullFileName);*/
|
||||
//var fullFileName = "\\images\\" + category + "\\" + filename + ".tiff";
|
||||
|
||||
var image = Image.FromStream(input);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
||||
return ms.ToArray();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] ConvertTiffToJpeg(string fileName)
|
||||
{
|
||||
using (Image imageFile = Image.FromFile(fileName))
|
||||
{
|
||||
FrameDimension frameDimensions = new FrameDimension(
|
||||
imageFile.FrameDimensionsList[0]);
|
||||
|
||||
// Gets the number of pages from the tiff image (if multipage)
|
||||
int frameNum = imageFile.GetFrameCount(frameDimensions);
|
||||
string[] jpegPaths = new string[frameNum];
|
||||
|
||||
for (int frame = 0; frame < frameNum; frame++)
|
||||
{
|
||||
// Selects one frame at a time and save as jpeg.
|
||||
imageFile.SelectActiveFrame(frameDimensions, frame);
|
||||
using (Bitmap bmp = new Bitmap(imageFile))
|
||||
{
|
||||
jpegPaths[frame] = String.Format("{0}\\{1}{2}.jpg",
|
||||
Path.GetDirectoryName(fileName),
|
||||
Path.GetFileNameWithoutExtension(fileName),
|
||||
frame);
|
||||
bmp.Save(jpegPaths[frame], ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
|
||||
return jpegPaths;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
|
||||
public class ImageExtractor : IExtractor
|
||||
{
|
||||
|
||||
public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
|
||||
{
|
||||
byte[] imageArray = ImageOps.GetByteArrayforImage(input.BaseStream);
|
||||
output.Set<byte[]>(0, imageArray);
|
||||
yield return output.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
|
||||
public class ImageOutputter : IOutputter
|
||||
{
|
||||
public override void Output(IRow input, IUnstructuredWriter output)
|
||||
{
|
||||
var obj = input.Get<object>(0);
|
||||
byte[] imageArray = (byte[])obj;
|
||||
using (MemoryStream ms = new MemoryStream(imageArray))
|
||||
{
|
||||
var image = Image.FromStream(ms);
|
||||
image.Save(output.BaseStream, ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using Microsoft.Analytics.Interfaces;
|
||||
using Microsoft.Analytics.Types.Sql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Images
|
||||
{
|
||||
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
|
||||
public class ImageExtractor : IExtractor
|
||||
{
|
||||
public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
|
||||
{
|
||||
byte[] imageArray = ImageOps.GetByteArrayforImage(input.BaseStream);
|
||||
output.Set<byte[]>(0, imageArray);
|
||||
yield return output.AsReadOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
using Microsoft.Analytics.Interfaces;
|
||||
using Microsoft.Analytics.Types.Sql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Images
|
||||
{
|
||||
// Helper class that binds together a stream and an image so that they can be disposed together.
|
||||
// It is needed because the stream must stay open for as long as the image is being used.
|
||||
class StreamImage : IDisposable
|
||||
{
|
||||
private MemoryStream mMemoryStream;
|
||||
public Image mImage;
|
||||
|
||||
public StreamImage(byte[] inBytes)
|
||||
{
|
||||
mMemoryStream = new MemoryStream(inBytes);
|
||||
mImage = null;
|
||||
try
|
||||
{
|
||||
mImage = Image.FromStream(mMemoryStream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (mImage == null)
|
||||
{
|
||||
mMemoryStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
mImage.Dispose();
|
||||
}
|
||||
finally
|
||||
{
|
||||
mMemoryStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sample image utilities and operations.
|
||||
public class ImageOps
|
||||
{
|
||||
// The quality setting for generated JPEG files.
|
||||
private const long JPEG_QUALITY = 90;
|
||||
|
||||
// Utility: convert a byte array into an image.
|
||||
private static StreamImage byteArrayToImage(byte[] inBytes)
|
||||
{
|
||||
return new StreamImage(inBytes);
|
||||
}
|
||||
|
||||
// Utility: convert an image into a byte array containing a JPEG encoding of the image.
|
||||
private static byte[] imageToByteArray(Image inImage)
|
||||
{
|
||||
using (MemoryStream outStream = new MemoryStream())
|
||||
{
|
||||
ImageCodecInfo jpegCodec = null;
|
||||
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
|
||||
{
|
||||
if (codec.FormatID == ImageFormat.Jpeg.Guid)
|
||||
{
|
||||
jpegCodec = codec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jpegCodec == null)
|
||||
{
|
||||
throw new MissingMemberException("Cannot find JPEG encoder");
|
||||
}
|
||||
using (EncoderParameters ep = new EncoderParameters(1))
|
||||
{
|
||||
using (EncoderParameter p = new EncoderParameter(Encoder.Quality, JPEG_QUALITY))
|
||||
{
|
||||
ep.Param[0] = p;
|
||||
inImage.Save(outStream, jpegCodec, ep);
|
||||
return outStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Utility: draw the input image to the output image within the given region (at high quality).
|
||||
private static void drawImage(Image inImage, Bitmap outImage, Rectangle region)
|
||||
{
|
||||
outImage.SetResolution(inImage.HorizontalResolution, inImage.VerticalResolution);
|
||||
using (Graphics g = Graphics.FromImage(outImage))
|
||||
{
|
||||
// Clear background pixels, if any will remain after the drawing below.
|
||||
if ((region.X != 0) ||
|
||||
(region.Y != 0) ||
|
||||
(region.Height != outImage.Height) ||
|
||||
(region.Width != outImage.Width))
|
||||
{
|
||||
g.Clear(Color.Black);
|
||||
}
|
||||
// Draw image at high quality.
|
||||
g.CompositingMode = CompositingMode.SourceCopy;
|
||||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
using (ImageAttributes attributes = new ImageAttributes())
|
||||
{
|
||||
attributes.SetWrapMode(WrapMode.TileFlipXY);
|
||||
g.DrawImage(inImage, region, 0, 0, inImage.Width, inImage.Height, GraphicsUnit.Pixel, attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: return the value of an image property (provided it's a string or integer).
|
||||
// Use property ID 8298 for copyright.
|
||||
// See https://msdn.microsoft.com/en-us/library/ms534416.aspx for additional IDs.
|
||||
public static string getImageProperty(byte[] inBytes, int propertyId)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
foreach (PropertyItem propItem in inImage.mImage.PropertyItems)
|
||||
{
|
||||
if (propItem.Id == propertyId)
|
||||
{
|
||||
return (propItem.Type == 2) ? System.Text.Encoding.UTF8.GetString(propItem.Value) : propItem.Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Operation: rotate an image by 90, 180, or 270 degrees.
|
||||
public static byte[] rotateImage(byte[] inBytes, int rotateType)
|
||||
{
|
||||
RotateFlipType rotateFlipType;
|
||||
switch (rotateType)
|
||||
{
|
||||
case 1:
|
||||
rotateFlipType = RotateFlipType.Rotate90FlipNone;
|
||||
break;
|
||||
case 2:
|
||||
rotateFlipType = RotateFlipType.Rotate180FlipNone;
|
||||
break;
|
||||
case 3:
|
||||
rotateFlipType = RotateFlipType.Rotate270FlipNone;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Invalid type");
|
||||
}
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
inImage.mImage.RotateFlip(rotateFlipType);
|
||||
return imageToByteArray(inImage.mImage);
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: scale an image by a scale factor.
|
||||
public static byte[] scaleImageBy(byte[] inBytes, float scaleFactor)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
int outWidth = (int)(inImage.mImage.Width * scaleFactor);
|
||||
int outHeight = (int)(inImage.mImage.Height * scaleFactor);
|
||||
using (Bitmap outImage = new Bitmap(outWidth, outHeight))
|
||||
{
|
||||
drawImage(inImage.mImage, outImage, new Rectangle(0, 0, outWidth, outHeight));
|
||||
return imageToByteArray(outImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: scale an image to the given dimensions.
|
||||
public static byte[] scaleImageTo(byte[] inBytes, int outWidth, int outHeight)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
int x, y, w, h;
|
||||
int iWoH = inImage.mImage.Width * outHeight;
|
||||
int iHoW = inImage.mImage.Height * outWidth;
|
||||
if (iWoH < iHoW)
|
||||
{
|
||||
w = (int)((double)(iWoH) / inImage.mImage.Height);
|
||||
h = outHeight;
|
||||
x = (int)((outWidth - w) / 2.0);
|
||||
y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = outWidth;
|
||||
h = (int)((double)(iHoW) / inImage.mImage.Width);
|
||||
x = 0;
|
||||
y = (int)((outHeight - h) / 2.0);
|
||||
}
|
||||
using (Bitmap outImage = new Bitmap(outWidth, outHeight))
|
||||
{
|
||||
drawImage(inImage.mImage, outImage, new Rectangle(x, y, w, h));
|
||||
return imageToByteArray(outImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] GetByteArrayforImage(Stream input)
|
||||
{
|
||||
try
|
||||
{
|
||||
//var fullFileName = "C:\\Users\\rukmanig\\AppData\\Local\\USQLDataRoot\\images\\" + category + "\\" + filename + ".tiff";
|
||||
/* var fullFileName = @"/rukmanig/images/" + filename + ".tiff";
|
||||
string[] jpgFileName = ConvertTiffToJpeg(fullFileName);*/
|
||||
//var fullFileName = "\\images\\" + category + "\\" + filename + ".tiff";
|
||||
|
||||
var image = Image.FromStream(input);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
||||
return ms.ToArray();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] ConvertTiffToJpeg(string fileName)
|
||||
{
|
||||
using (Image imageFile = Image.FromFile(fileName))
|
||||
{
|
||||
FrameDimension frameDimensions = new FrameDimension(
|
||||
imageFile.FrameDimensionsList[0]);
|
||||
|
||||
// Gets the number of pages from the tiff image (if multipage)
|
||||
int frameNum = imageFile.GetFrameCount(frameDimensions);
|
||||
string[] jpegPaths = new string[frameNum];
|
||||
|
||||
for (int frame = 0; frame < frameNum; frame++)
|
||||
{
|
||||
// Selects one frame at a time and save as jpeg.
|
||||
imageFile.SelectActiveFrame(frameDimensions, frame);
|
||||
using (Bitmap bmp = new Bitmap(imageFile))
|
||||
{
|
||||
jpegPaths[frame] = String.Format("{0}\\{1}{2}.jpg",
|
||||
Path.GetDirectoryName(fileName),
|
||||
Path.GetFileNameWithoutExtension(fileName),
|
||||
frame);
|
||||
bmp.Save(jpegPaths[frame], ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
|
||||
return jpegPaths;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using Microsoft.Analytics.Interfaces;
|
||||
using Microsoft.Analytics.Types.Sql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Images
|
||||
{
|
||||
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
|
||||
public class ImageOutputter : IOutputter
|
||||
{
|
||||
public override void Output(IRow input, IUnstructuredWriter output)
|
||||
{
|
||||
var obj = input.Get<object>(0);
|
||||
byte[] imageArray = (byte[])obj;
|
||||
using (MemoryStream ms = new MemoryStream(imageArray))
|
||||
{
|
||||
var image = Image.FromStream(ms);
|
||||
image.Save(output.BaseStream, ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{97595649-6032-45EE-87D6-F780C0FE4A51}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Images</RootNamespace>
|
||||
<AssemblyName>Images</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Analytics.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f877b68b06e0b5e, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.Analytics.Types, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f877b68b06e0b5e, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ImageExtractor.cs" />
|
||||
<Compile Include="ImageOps.cs" />
|
||||
<Compile Include="ImageOutputter.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Images")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Images")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("97595649-6032-45ee-87d6-f780c0fe4a51")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,27 @@
|
|||
using Microsoft.Analytics.Interfaces;
|
||||
using Microsoft.Analytics.Types.Sql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Images
|
||||
{
|
||||
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
|
||||
public class ImageExtractor : IExtractor
|
||||
{
|
||||
public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
|
||||
{
|
||||
byte[] imageArray = ImageOps.GetByteArrayforImage(input.BaseStream);
|
||||
output.Set<byte[]>(0, imageArray);
|
||||
yield return output.AsReadOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
using Microsoft.Analytics.Interfaces;
|
||||
using Microsoft.Analytics.Types.Sql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Images
|
||||
{
|
||||
// Helper class that binds together a stream and an image so that they can be disposed together.
|
||||
// It is needed because the stream must stay open for as long as the image is being used.
|
||||
class StreamImage : IDisposable
|
||||
{
|
||||
private MemoryStream mMemoryStream;
|
||||
public Image mImage;
|
||||
|
||||
public StreamImage(byte[] inBytes)
|
||||
{
|
||||
mMemoryStream = new MemoryStream(inBytes);
|
||||
mImage = null;
|
||||
try
|
||||
{
|
||||
mImage = Image.FromStream(mMemoryStream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (mImage == null)
|
||||
{
|
||||
mMemoryStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
mImage.Dispose();
|
||||
}
|
||||
finally
|
||||
{
|
||||
mMemoryStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sample image utilities and operations.
|
||||
public class ImageOps
|
||||
{
|
||||
// The quality setting for generated JPEG files.
|
||||
private const long JPEG_QUALITY = 90;
|
||||
|
||||
// Utility: convert a byte array into an image.
|
||||
private static StreamImage byteArrayToImage(byte[] inBytes)
|
||||
{
|
||||
return new StreamImage(inBytes);
|
||||
}
|
||||
|
||||
// Utility: convert an image into a byte array containing a JPEG encoding of the image.
|
||||
private static byte[] imageToByteArray(Image inImage)
|
||||
{
|
||||
using (MemoryStream outStream = new MemoryStream())
|
||||
{
|
||||
ImageCodecInfo jpegCodec = null;
|
||||
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
|
||||
{
|
||||
if (codec.FormatID == ImageFormat.Jpeg.Guid)
|
||||
{
|
||||
jpegCodec = codec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jpegCodec == null)
|
||||
{
|
||||
throw new MissingMemberException("Cannot find JPEG encoder");
|
||||
}
|
||||
using (EncoderParameters ep = new EncoderParameters(1))
|
||||
{
|
||||
using (EncoderParameter p = new EncoderParameter(Encoder.Quality, JPEG_QUALITY))
|
||||
{
|
||||
ep.Param[0] = p;
|
||||
inImage.Save(outStream, jpegCodec, ep);
|
||||
return outStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Utility: draw the input image to the output image within the given region (at high quality).
|
||||
private static void drawImage(Image inImage, Bitmap outImage, Rectangle region)
|
||||
{
|
||||
outImage.SetResolution(inImage.HorizontalResolution, inImage.VerticalResolution);
|
||||
using (Graphics g = Graphics.FromImage(outImage))
|
||||
{
|
||||
// Clear background pixels, if any will remain after the drawing below.
|
||||
if ((region.X != 0) ||
|
||||
(region.Y != 0) ||
|
||||
(region.Height != outImage.Height) ||
|
||||
(region.Width != outImage.Width))
|
||||
{
|
||||
g.Clear(Color.Black);
|
||||
}
|
||||
// Draw image at high quality.
|
||||
g.CompositingMode = CompositingMode.SourceCopy;
|
||||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
using (ImageAttributes attributes = new ImageAttributes())
|
||||
{
|
||||
attributes.SetWrapMode(WrapMode.TileFlipXY);
|
||||
g.DrawImage(inImage, region, 0, 0, inImage.Width, inImage.Height, GraphicsUnit.Pixel, attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: return the value of an image property (provided it's a string or integer).
|
||||
// Use property ID 8298 for copyright.
|
||||
// See https://msdn.microsoft.com/en-us/library/ms534416.aspx for additional IDs.
|
||||
public static string getImageProperty(byte[] inBytes, int propertyId)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
foreach (PropertyItem propItem in inImage.mImage.PropertyItems)
|
||||
{
|
||||
if (propItem.Id == propertyId)
|
||||
{
|
||||
return (propItem.Type == 2) ? System.Text.Encoding.UTF8.GetString(propItem.Value) : propItem.Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Operation: rotate an image by 90, 180, or 270 degrees.
|
||||
public static byte[] rotateImage(byte[] inBytes, int rotateType)
|
||||
{
|
||||
RotateFlipType rotateFlipType;
|
||||
switch (rotateType)
|
||||
{
|
||||
case 1:
|
||||
rotateFlipType = RotateFlipType.Rotate90FlipNone;
|
||||
break;
|
||||
case 2:
|
||||
rotateFlipType = RotateFlipType.Rotate180FlipNone;
|
||||
break;
|
||||
case 3:
|
||||
rotateFlipType = RotateFlipType.Rotate270FlipNone;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Invalid type");
|
||||
}
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
inImage.mImage.RotateFlip(rotateFlipType);
|
||||
return imageToByteArray(inImage.mImage);
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: scale an image by a scale factor.
|
||||
public static byte[] scaleImageBy(byte[] inBytes, float scaleFactor)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
int outWidth = (int)(inImage.mImage.Width * scaleFactor);
|
||||
int outHeight = (int)(inImage.mImage.Height * scaleFactor);
|
||||
using (Bitmap outImage = new Bitmap(outWidth, outHeight))
|
||||
{
|
||||
drawImage(inImage.mImage, outImage, new Rectangle(0, 0, outWidth, outHeight));
|
||||
return imageToByteArray(outImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operation: scale an image to the given dimensions.
|
||||
public static byte[] scaleImageTo(byte[] inBytes, int outWidth, int outHeight)
|
||||
{
|
||||
using (StreamImage inImage = byteArrayToImage(inBytes))
|
||||
{
|
||||
int x, y, w, h;
|
||||
int iWoH = inImage.mImage.Width * outHeight;
|
||||
int iHoW = inImage.mImage.Height * outWidth;
|
||||
if (iWoH < iHoW)
|
||||
{
|
||||
w = (int)((double)(iWoH) / inImage.mImage.Height);
|
||||
h = outHeight;
|
||||
x = (int)((outWidth - w) / 2.0);
|
||||
y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = outWidth;
|
||||
h = (int)((double)(iHoW) / inImage.mImage.Width);
|
||||
x = 0;
|
||||
y = (int)((outHeight - h) / 2.0);
|
||||
}
|
||||
using (Bitmap outImage = new Bitmap(outWidth, outHeight))
|
||||
{
|
||||
drawImage(inImage.mImage, outImage, new Rectangle(x, y, w, h));
|
||||
return imageToByteArray(outImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] GetByteArrayforImage(Stream input)
|
||||
{
|
||||
try
|
||||
{
|
||||
//var fullFileName = "C:\\Users\\rukmanig\\AppData\\Local\\USQLDataRoot\\images\\" + category + "\\" + filename + ".tiff";
|
||||
/* var fullFileName = @"/rukmanig/images/" + filename + ".tiff";
|
||||
string[] jpgFileName = ConvertTiffToJpeg(fullFileName);*/
|
||||
//var fullFileName = "\\images\\" + category + "\\" + filename + ".tiff";
|
||||
|
||||
var image = Image.FromStream(input);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
||||
return ms.ToArray();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] ConvertTiffToJpeg(string fileName)
|
||||
{
|
||||
using (Image imageFile = Image.FromFile(fileName))
|
||||
{
|
||||
FrameDimension frameDimensions = new FrameDimension(
|
||||
imageFile.FrameDimensionsList[0]);
|
||||
|
||||
// Gets the number of pages from the tiff image (if multipage)
|
||||
int frameNum = imageFile.GetFrameCount(frameDimensions);
|
||||
string[] jpegPaths = new string[frameNum];
|
||||
|
||||
for (int frame = 0; frame < frameNum; frame++)
|
||||
{
|
||||
// Selects one frame at a time and save as jpeg.
|
||||
imageFile.SelectActiveFrame(frameDimensions, frame);
|
||||
using (Bitmap bmp = new Bitmap(imageFile))
|
||||
{
|
||||
jpegPaths[frame] = String.Format("{0}\\{1}{2}.jpg",
|
||||
Path.GetDirectoryName(fileName),
|
||||
Path.GetFileNameWithoutExtension(fileName),
|
||||
frame);
|
||||
bmp.Save(jpegPaths[frame], ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
|
||||
return jpegPaths;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using Microsoft.Analytics.Interfaces;
|
||||
using Microsoft.Analytics.Types.Sql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Images
|
||||
{
|
||||
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
|
||||
public class ImageOutputter : IOutputter
|
||||
{
|
||||
public override void Output(IRow input, IUnstructuredWriter output)
|
||||
{
|
||||
var obj = input.Get<object>(0);
|
||||
byte[] imageArray = (byte[])obj;
|
||||
using (MemoryStream ms = new MemoryStream(imageArray))
|
||||
{
|
||||
var image = Image.FromStream(ms);
|
||||
image.Save(output.BaseStream, ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{97595649-6032-45EE-87D6-F780C0FE4A51}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Images</RootNamespace>
|
||||
<AssemblyName>Images</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Analytics.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f877b68b06e0b5e, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.Analytics.Types, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f877b68b06e0b5e, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ImageExtractor.cs" />
|
||||
<Compile Include="ImageOps.cs" />
|
||||
<Compile Include="ImageOutputter.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Images")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Images")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("97595649-6032-45ee-87d6-f780c0fe4a51")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
Загрузка…
Ссылка в новой задаче