Skip to content

Commit

Permalink
RoundBorders method implementation (#858)
Browse files Browse the repository at this point in the history
* RoundBorders method implementation
Issue: 104034

* Forgot to remove call to debugger

* Use Uri class to check if image its an URL

(cherry picked from commit cd56c70)
  • Loading branch information
tomas-sexenian committed Sep 11, 2023
1 parent 993727c commit ffc7e9b
Showing 1 changed file with 122 additions and 8 deletions.
130 changes: 122 additions & 8 deletions dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
using System.Threading.Tasks;
using System.Drawing.Imaging;
using System.Net.Http.Headers;
using Image = System.Drawing.Image;
using System.Net.Http;

namespace GeneXus.Utils
{
Expand Down Expand Up @@ -5551,20 +5553,65 @@ public static class GxImageUtil

private static Bitmap BitmapCreateFromStream(string filePathOrUrl)
{
using (Stream s = ImageFile(filePathOrUrl).GetStream())
Uri uri;
if (Uri.TryCreate(filePathOrUrl, UriKind.Absolute, out uri) && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
{
if (s != null)
return new Bitmap(s);
return null;
using (HttpClient httpClient = new HttpClient())
{
try
{
byte[] data = httpClient.GetByteArrayAsync(filePathOrUrl).Result;

Check failure on line 5563 in dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

View workflow job for this annotation

GitHub Actions / test-external-storages

Modify 'GxImageUtil.BitmapCreateFromStream(string)' to call 'HttpClient.GetByteArrayAsync(Uri)' instead of 'HttpClient.GetByteArrayAsync(string)'.

Check failure on line 5563 in dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

View workflow job for this annotation

GitHub Actions / test-external-storages

Modify 'GxImageUtil.BitmapCreateFromStream(string)' to call 'HttpClient.GetByteArrayAsync(Uri)' instead of 'HttpClient.GetByteArrayAsync(string)'.

Check failure on line 5563 in dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

View workflow job for this annotation

GitHub Actions / build

Modify 'GxImageUtil.BitmapCreateFromStream(string)' to call 'HttpClient.GetByteArrayAsync(Uri)' instead of 'HttpClient.GetByteArrayAsync(string)'.

Check failure on line 5563 in dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

View workflow job for this annotation

GitHub Actions / build

Modify 'GxImageUtil.BitmapCreateFromStream(string)' to call 'HttpClient.GetByteArrayAsync(Uri)' instead of 'HttpClient.GetByteArrayAsync(string)'.
using (MemoryStream mem = new MemoryStream(data))
{
return new Bitmap(mem);
}
}
catch
{
return null;
}
}
}
else
{
using (Stream s = ImageFile(filePathOrUrl).GetStream())
{
if (s != null)
return new Bitmap(s);
return null;
}
}

}
private static Image ImageCreateFromStream(string filePathOrUrl)
{
using (Stream s = ImageFile(filePathOrUrl).GetStream())
Uri uri;
if (Uri.TryCreate(filePathOrUrl, UriKind.Absolute, out uri) && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
{
if (s != null)
return Image.FromStream(s);
return null;
using (HttpClient httpClient = new HttpClient())
{
try
{
byte[] data = httpClient.GetByteArrayAsync(filePathOrUrl).Result;

Check failure on line 5595 in dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

View workflow job for this annotation

GitHub Actions / test-external-storages

Modify 'GxImageUtil.ImageCreateFromStream(string)' to call 'HttpClient.GetByteArrayAsync(Uri)' instead of 'HttpClient.GetByteArrayAsync(string)'.

Check failure on line 5595 in dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

View workflow job for this annotation

GitHub Actions / test-external-storages

Modify 'GxImageUtil.ImageCreateFromStream(string)' to call 'HttpClient.GetByteArrayAsync(Uri)' instead of 'HttpClient.GetByteArrayAsync(string)'.

Check failure on line 5595 in dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

View workflow job for this annotation

GitHub Actions / build

Modify 'GxImageUtil.ImageCreateFromStream(string)' to call 'HttpClient.GetByteArrayAsync(Uri)' instead of 'HttpClient.GetByteArrayAsync(string)'.

Check failure on line 5595 in dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

View workflow job for this annotation

GitHub Actions / build

Modify 'GxImageUtil.ImageCreateFromStream(string)' to call 'HttpClient.GetByteArrayAsync(Uri)' instead of 'HttpClient.GetByteArrayAsync(string)'.
using (MemoryStream mem = new MemoryStream(data))
{
return Image.FromStream(mem);
}
}
catch
{
return null;
}
}
}
else
{
using (Stream s = ImageFile(filePathOrUrl).GetStream())
{
if (s != null)
return Image.FromStream(s);
return null;
}
}
}

Expand Down Expand Up @@ -5651,6 +5698,68 @@ public static string Crop(string imageFile, int X, int Y, int Width, int Height)
}
return modifiedImage;
}
public static string RoundBorders(string imageFile, int topLeftRadius, int topRightRadius, int bottomLeftRadius, int bottomRightRadius)
{
string modifiedImage = string.Empty;
try
{
using (MemoryStream ms = new MemoryStream())
{
using (Image OriginalImage = ImageCreateFromStream(imageFile))
{
int w = OriginalImage.Width;
int h = OriginalImage.Height;

using (Bitmap roundedImage = new Bitmap(w, h))
{
roundedImage.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution);
using (Graphics g = Graphics.FromImage(roundedImage))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.Clear(Color.Transparent);

using (GraphicsPath path = new GraphicsPath())
{
path.StartFigure();
if (topLeftRadius > 0)
path.AddArc(0, 0, 2 * topLeftRadius, 2 * topLeftRadius, (float) 180, (float) 90);
path.AddLine(topLeftRadius, 0, w - topRightRadius, 0);
if (topRightRadius > 0)
path.AddArc(w - 2 * topRightRadius, 0, 2 * topRightRadius, 2 * topRightRadius, (float) 270, (float) 90);
path.AddLine(w, topRightRadius, w, h - bottomRightRadius);
if (bottomRightRadius > 0)
path.AddArc(w - 2 * bottomRightRadius, h - 2 * bottomRightRadius, 2 * bottomRightRadius, 2 * bottomRightRadius, (float) 0, (float) 90);
path.AddLine(w - bottomLeftRadius, h, bottomLeftRadius, h);
if (bottomLeftRadius > 0)
path.AddArc(0, h - 2 * bottomLeftRadius, 2 * bottomLeftRadius, 2 * bottomLeftRadius, (float) 90, (float) 90);
path.CloseFigure();

g.FillPath(Brushes.White, path);

using (TextureBrush br = new TextureBrush(new Bitmap(OriginalImage), WrapMode.Clamp))
{
g.FillPath(br, path);
}
}
}
// Rounded images are basically images with transparent rounded borders and jpg and jpeg formats do not
// support transparency, so we have to create a new identical image but in png format
if (imageFile.IndexOf(".jpg") > 0)
modifiedImage = Save(roundedImage, imageFile.Replace(".jpg", ".png"), ImageFormat.Png);
else if (imageFile.IndexOf(".jpeg") > 0)
modifiedImage = Save(roundedImage, imageFile.Replace(".jpeg", ".png"), ImageFormat.Png);
else
modifiedImage = Save(roundedImage, imageFile, OriginalImage.RawFormat);
}
}
}
}
catch (Exception ex)
{
GXLogging.Error(log, $"RoundBorders {imageFile} failed", ex);
}
return modifiedImage;
}
public static string Rotate(string imageFile, int angle)
{
string modifiedImage = string.Empty;
Expand Down Expand Up @@ -5738,6 +5847,11 @@ public static string Save(Image bitmap, string imageFile, ImageFormat format)
ms.Position = 0;
try
{
if (imageFile.StartsWith("http://") || imageFile.StartsWith("https://"))
{
Uri uri = new Uri(imageFile);
imageFile = Path.GetFileName(uri.AbsolutePath);
}
GxFile sourceImage = new GxFile(GxContext.StaticPhysicalPath(), imageFile);
string destinationImageName = FileUtil.getTempFileName(sourceImage.GetDirectory().GetAbsoluteName(), Path.GetFileNameWithoutExtension(sourceImage.GetName()), sourceImage.GetExtension());
GxFile destinationImage = new GxFile(GxContext.StaticPhysicalPath(), destinationImageName);
Expand Down

0 comments on commit ffc7e9b

Please sign in to comment.