mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: ae4de1addaed801930aea365f4bc0a87d03f6e3f Former-commit-id: bb1e39e2ef759b391e88b7f3fbfd98ea97913b3f Former-commit-id: 97d2de47e68c5dafc524656ec3d95c1c1f72e7c2af/merge-core
5 changed files with 170 additions and 0 deletions
@ -0,0 +1,84 @@ |
|||
// <copyright file="EntropyCrop.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
using Processors; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{T,TP}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Adjusts an image so that its orientation is suitable for viewing.
|
|||
/// </summary>
|
|||
/// <typeparam name="T">The pixel format.</typeparam>
|
|||
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
|
|||
/// <param name="source">The image to crop.</param>
|
|||
/// <returns>The <see cref="Image"/></returns>
|
|||
public static Image<T, TP> AutoOrient<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) |
|||
where T : IPackedVector<TP> |
|||
where TP : struct |
|||
{ |
|||
Orientation orientation = GetExifOrientation(source); |
|||
|
|||
switch (orientation) |
|||
{ |
|||
case Orientation.Unknown: |
|||
case Orientation.TopLeft: |
|||
default: |
|||
return source; |
|||
|
|||
case Orientation.TopRight: |
|||
return source.Flip(FlipType.Horizontal, progressHandler); |
|||
|
|||
case Orientation.BottomRight: |
|||
return source.Rotate(RotateType.Rotate180, progressHandler); |
|||
|
|||
case Orientation.BottomLeft: |
|||
return source.Flip(FlipType.Vertical, progressHandler); |
|||
|
|||
case Orientation.LeftTop: |
|||
return source |
|||
.Rotate(RotateType.Rotate90, progressHandler) |
|||
.Flip(FlipType.Horizontal, progressHandler); |
|||
|
|||
case Orientation.RightTop: |
|||
return source.Rotate(RotateType.Rotate90, progressHandler); |
|||
|
|||
case Orientation.RightBottom: |
|||
return source |
|||
.Flip(FlipType.Vertical, progressHandler) |
|||
.Rotate(RotateType.Rotate270, progressHandler); |
|||
|
|||
case Orientation.LeftBottom: |
|||
return source.Rotate(RotateType.Rotate270, progressHandler); |
|||
} |
|||
} |
|||
|
|||
private static Orientation GetExifOrientation<T, TP>(Image<T, TP> source) |
|||
where T : IPackedVector<TP> |
|||
where TP : struct |
|||
{ |
|||
if (source.ExifProfile == null) |
|||
{ |
|||
return Orientation.Unknown; |
|||
} |
|||
|
|||
ExifValue value = source.ExifProfile.GetValue(ExifTag.Orientation); |
|||
if (value == null) |
|||
{ |
|||
return Orientation.Unknown; |
|||
} |
|||
|
|||
Orientation orientation = (Orientation)value.Value; |
|||
|
|||
source.ExifProfile.SetValue(ExifTag.Orientation, (ushort)Orientation.TopLeft); |
|||
|
|||
return orientation; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
// <copyright file="AnchorPosition.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
internal enum Orientation : ushort |
|||
{ |
|||
Unknown = 0, |
|||
TopLeft = 1, |
|||
TopRight = 2, |
|||
BottomRight = 3, |
|||
BottomLeft = 4, |
|||
LeftTop = 5, |
|||
RightTop = 6, |
|||
RightBottom = 7, |
|||
LeftBottom = 8 |
|||
} |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
// <copyright file="RotateFlipTest.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore.Tests |
|||
{ |
|||
using System.IO; |
|||
using Xunit; |
|||
|
|||
public class AutoOrientTests : FileTestBase |
|||
{ |
|||
public static readonly TheoryData<RotateType, FlipType, ushort> OrientationValues |
|||
= new TheoryData<RotateType, FlipType, ushort> |
|||
{ |
|||
{ RotateType.None, FlipType.None, 0 }, |
|||
{ RotateType.None, FlipType.None, 1 }, |
|||
{ RotateType.None, FlipType.Horizontal, 2 }, |
|||
{ RotateType.Rotate180, FlipType.None, 3 }, |
|||
{ RotateType.Rotate180, FlipType.Horizontal, 4 }, |
|||
{ RotateType.Rotate90, FlipType.Horizontal, 5 }, |
|||
{ RotateType.Rotate270, FlipType.None, 6 }, |
|||
{ RotateType.Rotate90, FlipType.Vertical, 7 }, |
|||
{ RotateType.Rotate90, FlipType.None, 8 }, |
|||
}; |
|||
|
|||
[Theory] |
|||
[MemberData("OrientationValues")] |
|||
public void ImageShouldFlip(RotateType rotateType, FlipType flipType, ushort orientation) |
|||
{ |
|||
const string path = "TestOutput/AutoOrient"; |
|||
if (!Directory.Exists(path)) |
|||
{ |
|||
Directory.CreateDirectory(path); |
|||
} |
|||
|
|||
string file = TestImages.Bmp.F; |
|||
|
|||
using (FileStream stream = File.OpenRead(file)) |
|||
{ |
|||
string filename = Path.GetFileNameWithoutExtension(file) + "-" + orientation + Path.GetExtension(file); |
|||
|
|||
Image image = new Image(stream); |
|||
image.ExifProfile = new ExifProfile(); |
|||
image.ExifProfile.SetValue(ExifTag.Orientation, orientation); |
|||
|
|||
using (FileStream before = File.OpenWrite($"{path}/before-{filename}")) |
|||
{ |
|||
using (FileStream after = File.OpenWrite($"{path}/after-{filename}")) |
|||
{ |
|||
image.RotateFlip(rotateType, flipType) |
|||
.Save(before) |
|||
.AutoOrient() |
|||
.Save(after); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:6da008d2b285b2db946e6d4ebf8569b0ddd4a05ef273b38304cb65afccac87b3 |
|||
size 65502 |
|||
Loading…
Reference in new issue