Merge pull request #43 from rukmanig/rukmanig-image

Add sample code to process images using U-SQL
This commit is contained in:
rukmanig 2016-06-16 18:05:11 -05:00 коммит произвёл GitHub
Родитель 823186708f ed16800765
Коммит 01d91b3944
21 изменённых файлов: 1724 добавлений и 0 удалений

Просмотреть файл

@ -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")]