Skip to content

Instantly share code, notes, and snippets.

@AlBannaTechno
Last active July 12, 2021 13:40
Show Gist options
  • Save AlBannaTechno/ed8451f3f4a78cd66e900261e7d64e90 to your computer and use it in GitHub Desktop.
Save AlBannaTechno/ed8451f3f4a78cd66e900261e7d64e90 to your computer and use it in GitHub Desktop.
// Part Of SmartTech.NGOIPPF.Application
// All rights reserved © 2021 AlBannaTechno(OsamaAlBanna)
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace SmartTech.NGOIPPF.Helper
{
/// <summary>
/// some image non related helpers
/// <b>this class should only tested with unit test</b>
/// </summary>
public static class ImageHelper
{
/// <summary>
/// <b>be aware of the performance of this method, since this will firstly convert
/// the byte array to image</b>
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
public static string GetExtension(byte[] arr)
{
var img = ByteArrayToImage(arr);
if (Equals(img.RawFormat, ImageFormat.Png))
{
return nameof(ImageFormat.Png);
}
if (Equals(img.RawFormat, ImageFormat.Jpeg))
{
return nameof(ImageFormat.Jpeg);
}
if (Equals(img.RawFormat, ImageFormat.Gif))
{
return nameof(ImageFormat.Gif);
}
return null;
}
public static Image ByteArrayToImage( byte[] bmpBytes )
{
Image image = null;
using( MemoryStream stream = new MemoryStream( bmpBytes ) )
{
image = Image.FromStream( stream );
}
return image;
}
}
}
/// <summary>
/// Update user profile with the next cases
/// * Update username
/// * Update email
/// * Update Image: image file can be both base64 or link
/// * link, should exist as it
/// * base64 should decrypted back to the original file, then uploaded to the server
/// </summary>
/// <param name="profile"></param>
public async Task UpdateProfile(UpdateProfileInput profile)
{
var user = await UserManager.FindByNameAsync(profile.Name);
if (user == null) { return; }
var result = UploadProfileImageToLocalStorage(profile.Image, user.Id);
if (result.isLink)
{
// ?
}
var attachment = new CreateOrEditAttachmentDto
{
Extension = result.ext,
FileName = result.filename,
FilePath = result.filepath,
ObjectType = ObjectTypeEnum.UserProfileImage,
// TODO: check this || invalid conversion || try to parse
ObjectTypeId = user.TenantId,
// specified from the team, must be with the same value in the first seeding
AttachmentTypeId = 2,
CreatedOn = DateTime.Now
};
await _attachmentsAppService.CreateOrEdit(attachment);
// ?
user.ProfilePictureId = attachment.Id;
}
/// <summary>
///
/// </summary>
/// <param name="file"></param>
/// <param name="id"></param>
/// <returns>Extension extracted from metadata</returns>
private (string filename, string filepath, string ext, bool isLink) UploadProfileImageToLocalStorage(string file, long id)
{
if (file.StartsWith("http"))
{
return (file, file, null, true);
}
// TODO: must test this logic
var base64 = file.Substring(file.IndexOf(',') + 1);
var data = Convert.FromBase64String(base64);
// TODO: this method should replaced due to high CPU costs
var ext = ImageHelper.GetExtension(data);
var filename = $"{DateTime.Now.Millisecond.ToString()}.{ext}";
var filePath = $"attachment\\{ObjectTypeEnum.UserProfileImage}\\{id}\\{filename}";
File.WriteAllBytes($"{_environment.WebRootPath}\\{filePath}", data);
filePath = _configurationRoot["App:ServerRootAddress"] + filePath.Replace('\\', '/');
return (filename, filePath, ext, false);
}
// Part Of SmartTech.NGOIPPF.Application.Shared
using System.ComponentModel.DataAnnotations;
using Abp.Authorization.Users;
namespace SmartTech.NGOIPPF.Authorization.Users.Profile.Dto
{
public class UpdateProfileInput
{
[Required]
[StringLength(UserConsts.MaxPhoneNumberLength)]
public string PhoneNumber { get; set; }
[Required]
[StringLength(AbpUserBase.MaxNameLength)]
public string Name { get; set; }
[StringLength(AbpUserBase.MaxEmailAddressLength)]
public string Email { get; set; }
public string Image { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment