Skip to content

Commit e568c50

Browse files
Image API support when Storage is Enabled (#554)
* Download Storage External Files to Local when using Image API * Changed to Use Stream aPI * Remove unused code * Renames * - Add UnitTest - Support for Crop, Resize, FlipMethods * Minor * Preserve Image Format * Go back to bmp to avoid exceptions Co-authored-by: claudiamurialdo <33756655+claudiamurialdo@users.noreply.github.com>
1 parent a9bf3b3 commit e568c50

File tree

8 files changed

+188
-47
lines changed

8 files changed

+188
-47
lines changed

dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

Lines changed: 62 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
using GeneXus.Services;
4444
using GeneXus.Http;
4545
using System.Security;
46+
using System.Drawing.Imaging;
4647

4748
namespace GeneXus.Utils
4849
{
@@ -5458,10 +5459,21 @@ public static class GxImageUtil
54585459
{
54595460
static readonly ILog log = log4net.LogManager.GetLogger(typeof(GxImageUtil));
54605461

5461-
private static string ImageAbsolutePath(string originalFileLocation)
5462+
private static Bitmap BitmapCreateFromStream(string filePathOrUrl)
54625463
{
5463-
return ImageFile(originalFileLocation).GetAbsoluteName();
5464+
using (Stream s = ImageFile(filePathOrUrl).GetStream())
5465+
{
5466+
return new Bitmap(s);
5467+
}
5468+
}
5469+
private static Image ImageCreateFromStream(string filePathOrUrl)
5470+
{
5471+
using (Stream s = ImageFile(filePathOrUrl).GetStream())
5472+
{
5473+
return Image.FromStream(s);
5474+
}
54645475
}
5476+
54655477
private static GxFile ImageFile(string originalFileLocation)
54665478
{
54675479
return new GxFile(GxContext.StaticPhysicalPath(), originalFileLocation);
@@ -5470,11 +5482,10 @@ private static GxFile ImageFile(string originalFileLocation)
54705482
public static string Resize(string imageFile, int width, int height, bool keepAspectRatio)
54715483
{
54725484
try
5473-
{
5474-
int newheight = height;
5475-
string originalFileLocation = ImageAbsolutePath(imageFile);
5476-
using (Image image = Image.FromFile(ImageAbsolutePath(originalFileLocation)))
5485+
{
5486+
using (Image image = ImageCreateFromStream(imageFile))
54775487
{
5488+
int newheight = height;
54785489
// Prevent using images internal thumbnail
54795490
image.RotateFlip(RotateFlipType.Rotate180FlipNone);
54805491
image.RotateFlip(RotateFlipType.Rotate180FlipNone);
@@ -5484,8 +5495,9 @@ public static string Resize(string imageFile, int width, int height, bool keepAs
54845495
double resize = (double)image.Width / (double)width;//get the resize vector
54855496
newheight = (int)(image.Height / resize);// set the new heigth of the current image
54865497
}//return the image resized to the given heigth and width
5487-
image.GetThumbnailImage(width, newheight, null, IntPtr.Zero).Save(originalFileLocation);
5488-
}
5498+
Image output = image.GetThumbnailImage(width, newheight, null, IntPtr.Zero);
5499+
Save(output, imageFile, ImageFormat.Bmp);
5500+
}
54895501
}
54905502
catch (Exception ex)
54915503
{
@@ -5497,13 +5509,13 @@ public static string Scale(string imageFile, int percent)
54975509
{
54985510
try
54995511
{
5500-
string originalFileLocation = ImageAbsolutePath(imageFile);
55015512
int width, height;
5502-
using (Image image = Image.FromFile(originalFileLocation))
5513+
using (Image image = ImageCreateFromStream(imageFile))
55035514
{
55045515
width = image.Size.Width * percent / 100;
55055516
height = image.Size.Height * percent / 100;
55065517
}
5518+
55075519
return Resize(imageFile, width, height, true);
55085520
}
55095521
catch (Exception ex)
@@ -5517,9 +5529,8 @@ public static string Crop(string imageFile, int X, int Y, int Width, int Height)
55175529
try
55185530
{
55195531
using (MemoryStream ms = new MemoryStream())
5520-
{
5521-
string originalFileLocation = ImageAbsolutePath(imageFile);
5522-
using (Image OriginalImage = Image.FromFile(originalFileLocation))
5532+
{
5533+
using (Image OriginalImage = ImageCreateFromStream(imageFile))
55235534
{
55245535
using (Bitmap bmp = new Bitmap(Width, Height))
55255536
{
@@ -5529,15 +5540,11 @@ public static string Crop(string imageFile, int X, int Y, int Width, int Height)
55295540
Graphic.SmoothingMode = SmoothingMode.AntiAlias;
55305541
Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
55315542
Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
5532-
Graphic.DrawImage(OriginalImage, new Rectangle(0, 0, Width, Height), X, Y, Width, Height, GraphicsUnit.Pixel);
5533-
bmp.Save(ms, OriginalImage.RawFormat);
5543+
Graphic.DrawImage(OriginalImage, new Rectangle(0, 0, Width, Height), X, Y, Width, Height, GraphicsUnit.Pixel);
5544+
Save(bmp, imageFile, OriginalImage.RawFormat);
55345545
}
55355546
}
55365547
}
5537-
using (FileStream file = new FileStream(originalFileLocation, FileMode.Open, FileAccess.Write))
5538-
{
5539-
ms.WriteTo(file);
5540-
}
55415548
}
55425549
}
55435550
catch (Exception ex)
@@ -5548,13 +5555,11 @@ public static string Crop(string imageFile, int X, int Y, int Width, int Height)
55485555
}
55495556
public static string Rotate(string imageFile, int angle)
55505557
{
5551-
55525558
try
55535559
{
55545560
using (MemoryStream ms = new MemoryStream())
5555-
{
5556-
string originalFileLocation = ImageAbsolutePath(imageFile);
5557-
using (Image OriginalImage = Image.FromFile(originalFileLocation))
5561+
{
5562+
using (Image OriginalImage = ImageCreateFromStream(imageFile))
55585563
{
55595564
using (Bitmap rotatedImage = new Bitmap(OriginalImage.Width, OriginalImage.Height))
55605565
{
@@ -5568,12 +5573,9 @@ public static string Rotate(string imageFile, int angle)
55685573
g.DrawImage(OriginalImage, new Point(0, 0));
55695574
}
55705575
rotatedImage.Save(ms, OriginalImage.RawFormat);
5576+
Save(rotatedImage, imageFile, OriginalImage.RawFormat);
55715577
}
5572-
}
5573-
using (FileStream file = new FileStream(originalFileLocation, FileMode.Open, FileAccess.Write))
5574-
{
5575-
ms.WriteTo(file);
5576-
}
5578+
}
55775579
}
55785580
}
55795581
catch (Exception ex)
@@ -5582,15 +5584,14 @@ public static string Rotate(string imageFile, int angle)
55825584
}
55835585
return imageFile;
55845586
}
5585-
public static string FlipHorizontally(string imageFile) {
5586-
5587+
public static string FlipHorizontally(string imageFile)
5588+
{
55875589
try
55885590
{
5589-
string originalFileLocation = ImageAbsolutePath(imageFile);
5590-
using (Bitmap bmp = new Bitmap(originalFileLocation))
5591+
using (Bitmap bmp = BitmapCreateFromStream(imageFile))
55915592
{
55925593
bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
5593-
bmp.Save(originalFileLocation);
5594+
return Save(bmp, imageFile, bmp.RawFormat);
55945595
}
55955596
}
55965597
catch (Exception ex)
@@ -5603,11 +5604,10 @@ public static string FlipVertically(string imageFile)
56035604
{
56045605
try
56055606
{
5606-
string originalFileLocation = ImageAbsolutePath(imageFile);
5607-
using (Bitmap bmp = new Bitmap(originalFileLocation))
5607+
using (Bitmap bmp = BitmapCreateFromStream(imageFile))
56085608
{
56095609
bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
5610-
bmp.Save(originalFileLocation);
5610+
return Save(bmp, imageFile, bmp.RawFormat);
56115611
}
56125612
}
56135613
catch (Exception ex)
@@ -5617,12 +5617,32 @@ public static string FlipVertically(string imageFile)
56175617
return imageFile;
56185618
}
56195619

5620+
public static string Save(Image bitmap, string imageFile, ImageFormat format)
5621+
{
5622+
using (MemoryStream ms = new MemoryStream())
5623+
{
5624+
try
5625+
{
5626+
bitmap.Save(ms, format);
5627+
}
5628+
catch (Exception) {
5629+
//In some cases, copied memory image fails to save when ImageFormat MemoryBmp
5630+
//https://stackoverflow.com/questions/9073619/image-save-crashing-value-cannot-be-null-r-nparameter-name-encoder
5631+
bitmap.Save(ms, ImageFormat.Bmp);
5632+
}
5633+
ms.Position = 0;
5634+
GxFile file = new GxFile(GxContext.StaticPhysicalPath(), imageFile);
5635+
file.Create(ms);
5636+
file.Close();
5637+
}
5638+
return imageFile;
5639+
}
5640+
56205641
public static int GetImageWidth(string imageFile)
56215642
{
56225643
try
5623-
{
5624-
string originalFileLocation = ImageAbsolutePath(imageFile);
5625-
using (Bitmap bmp = new Bitmap(originalFileLocation))
5644+
{
5645+
using (Bitmap bmp = BitmapCreateFromStream(imageFile))
56265646
{
56275647
return bmp.Width;
56285648
}
@@ -5633,12 +5653,11 @@ public static int GetImageWidth(string imageFile)
56335653
}
56345654
return 0;
56355655
}
5656+
56365657
public static int GetImageHeight(string imageFile)
56375658
{
5638-
try
5639-
{
5640-
string originalFileLocation = ImageAbsolutePath(imageFile);
5641-
using (Bitmap bmp = new Bitmap(originalFileLocation))
5659+
try {
5660+
using (Bitmap bmp = BitmapCreateFromStream(imageFile))
56425661
{
56435662
return bmp.Height;
56445663
}

dotnet/src/dotnetframework/GxClasses/Domain/GXFileIO.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ public GxExternalFileInfo(string objectPath, ExternalProvider provider, GxFileTy
426426
objectPath = !String.IsNullOrEmpty(objectPath) ? objectPath.Replace('\\', '/') : objectPath;
427427
_provider = provider;
428428
_fileTypeAtt = fileType;
429-
_name = objectPath;
429+
_name = StorageFactory.GetProviderObjectAbsoluteUriSafe(provider, objectPath);
430430

431431
Uri result;
432432
if (Uri.TryCreate(objectPath, UriKind.Absolute, out result) && result.IsAbsoluteUri)

dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,7 @@ public string Serialize(object Value, string Pic)
15941594
}
15951595
else
15961596
{
1597-
var sValue = Value as string;
1597+
string sValue = Value as string;
15981598
if (sValue != null)
15991599
{
16001600
return Serialize(context.localUtil.Format(sValue, Pic));
@@ -1819,7 +1819,7 @@ public void ProcessRequest(HttpContext httpContext)
18191819
sendCacheHeaders();
18201820
GXLogging.Debug(log, "HttpHeaders: ", DumpHeaders(httpContext));
18211821
sendAdditionalHeaders();
1822-
var clientid = context.ClientID; //Send clientid cookie (before response HasStarted) if necessary, since UseResponseBuffering is not in .netcore3.0
1822+
string clientid = context.ClientID; //Send clientid cookie (before response HasStarted) if necessary, since UseResponseBuffering is not in .netcore3.0
18231823
#endif
18241824
bool validSession = ValidWebSession();
18251825
if (validSession && IntegratedSecurityEnabled)
@@ -2201,7 +2201,7 @@ protected void LoadParameters(string value)
22012201
_params.Add(GXUtil.UrlDecode(elements[i]));
22022202
else
22032203
{
2204-
var parmNameValue = elements[i].Split('=');
2204+
string[] parmNameValue = elements[i].Split('=');
22052205
if (parmNameValue.Length > 1)
22062206
{
22072207
parmValue = GXUtil.UrlDecode(parmNameValue[1]);

dotnet/test/DotNetCoreUnitTest/DotNetCoreUnitTest.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
<Compile Include="..\DotNetUnitTest\PDF\apdfbasictest.cs" Link="PDF\apdfbasictest.cs" />
2828
<Compile Include="..\DotNetUnitTest\PDF\PDFTests.cs" Link="PDF\PDFTests.cs" />
2929
</ItemGroup>
30+
<ItemGroup>
31+
<Compile Include="..\DotNetUnitTest\ImageUtils\ImageUtilTest.cs" Link="ImageUtils\ImageUtilTest.cs" />
32+
33+
</ItemGroup>
3034
<ItemGroup>
3135
<EmbeddedResource Include="..\DotNetUnitTest\type_SdtItem.cs" Link="type_SdtItem.cs">
3236
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -132,6 +136,9 @@
132136
<None Update="private\mailmanagement_a.grp.json">
133137
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
134138
</None>
139+
<None Update="resources\bird-thumbnail.jpg">
140+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
141+
</None>
135142
<None Update="resources\text.txt">
136143
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
137144
</None>
111 KB
Loading

dotnet/test/DotNetUnitTest/DotNetUnitTest.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
<Generator>SettingsSingleFileGenerator</Generator>
6565
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
6666
</None>
67+
<None Update="resources\bird-thumbnail.jpg">
68+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
69+
</None>
6770
<None Update="resources\text.txt">
6871
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
6972
</None>

0 commit comments

Comments
 (0)