/// <summary> /// 上传头像 /// </summary> /// <param name="userId">用户ID</param> /// <param name="postedFile">上传的二进制头像文件</param> public static void UploadOriginalAvatar(this IUserService userService, long userId, Stream postedFile) { if (postedFile == null) { return; } Image image = Image.FromStream(postedFile); IUserProfileSettingsManager userProfileSettingsManager = DIContainer.Resolve <IUserProfileSettingsManager>(); UserProfileSettings userProfileSettings = userProfileSettingsManager.GetUserProfileSettings(); //检查是否需要缩放原图 if (image.Height > userProfileSettings.OriginalAvatarHeight || image.Width > userProfileSettings.OriginalAvatarWidth) { postedFile = ImageProcessor.Resize(postedFile, userProfileSettings.OriginalAvatarWidth, userProfileSettings.OriginalAvatarHeight, ResizeMethod.KeepAspectRatio); } string relativePath = GetAvatarRelativePath(userId); IStoreProvider storeProvider = DIContainer.Resolve <IStoreProvider>(); storeProvider.AddOrUpdateFile(relativePath, GetAvatarFileName(userId, AvatarSizeType.Original), postedFile); postedFile.Dispose(); //1、如果原图超过一定尺寸(可以配置宽高像素值)则原图保留前先缩小(原图如果太大,裁剪时不方便操作)再保存 }
/// <summary> /// 根据用户自己选择的尺寸及位置进行头像裁剪 /// </summary> /// <param name="userId">用户Id</param> /// <param name="srcWidth">需裁剪的宽度</param> /// <param name="srcHeight">需裁剪的高度</param> /// <param name="srcX">需裁剪的左上角点坐标</param> /// <param name="srcY">需裁剪的左上角点坐标</param> public static void CropAvatar(this IUserService userService, long userId, float srcWidth, float srcHeight, float srcX, float srcY) { IStoreProvider storeProvider = DIContainer.Resolve <IStoreProvider>(); IStoreFile iStoreFile = storeProvider.GetFile(GetAvatarRelativePath(userId), GetAvatarFileName(userId, AvatarSizeType.Original)); if (iStoreFile == null) { return; } User user = GetFullUser(userService, userId); if (user == null) { return; } bool isFirst = !(user.HasAvatar); string avatarRelativePath = GetAvatarRelativePath(userId).Replace(Path.DirectorySeparatorChar, '/'); avatarRelativePath = avatarRelativePath.Substring(AvatarDirectory.Length + 1); user.Avatar = avatarRelativePath + "/" + userId; IUserRepository userRepository = userService.GetUserRepository(); userRepository.UpdateAvatar(user, user.Avatar); IUserProfileSettingsManager userProfileSettingsManager = DIContainer.Resolve <IUserProfileSettingsManager>(); UserProfileSettings userProfileSettings = userProfileSettingsManager.GetUserProfileSettings(); using (Stream fileStream = iStoreFile.OpenReadStream()) { Stream bigImage = ImageProcessor.Crop(fileStream, new Rectangle((int)srcX, (int)srcY, (int)srcWidth, (int)srcHeight), userProfileSettings.AvatarWidth, userProfileSettings.AvatarHeight); Stream smallImage = ImageProcessor.Resize(bigImage, userProfileSettings.SmallAvatarWidth, userProfileSettings.SmallAvatarHeight, ResizeMethod.KeepAspectRatio); storeProvider.AddOrUpdateFile(GetAvatarRelativePath(userId), GetAvatarFileName(userId, AvatarSizeType.Big), bigImage); storeProvider.AddOrUpdateFile(GetAvatarRelativePath(userId), GetAvatarFileName(userId, AvatarSizeType.Small), smallImage); bigImage.Dispose(); smallImage.Dispose(); fileStream.Close(); } EventBus <User, CropAvatarEventArgs> .Instance().OnAfter(user, new CropAvatarEventArgs(isFirst)); //触发用户更新头像事件 }
/// <summary> /// 显示头像 /// </summary> /// <param name="user">用户对象</param> /// <param name="avatarSizeType">头像尺寸类别</param> /// <param name="link">链接到用户空间的地址</param> /// <param name="navigateTarget">链接类型</param> /// <param name="enableCachingInClient">是否允许在客户端缓存</param> /// <param name="htmlAttributes">html属性,例如:new RouteValueDictionary{{"Class","editor"},{"width","90%"}}</param> /// <returns></returns> public static MvcHtmlString ShowUserAvatar(this HtmlHelper htmlHelper, IUser user, string link, AvatarSizeType avatarSizeType = AvatarSizeType.Medium, HyperLinkTarget navigateTarget = HyperLinkTarget._blank, bool enableCachingInClient = true, RouteValueDictionary htmlAttributes = null, bool isShowUserCard = true, bool isShowTitle = false) { string avatarUrl = SiteUrls.Instance().UserAvatarUrl(user, avatarSizeType, enableCachingInClient); TagBuilder img = new TagBuilder("img"); if (htmlAttributes != null) { img.MergeAttributes(htmlAttributes); } img.MergeAttribute("src", avatarUrl); if (user != null) { img.MergeAttribute("alt", user.DisplayName); if (isShowTitle) { img.MergeAttribute("title", user.DisplayName); } } IUserProfileSettingsManager userProfileSettingsManager = DIContainer.Resolve <IUserProfileSettingsManager>(); UserProfileSettings userProfileSettings = userProfileSettingsManager.GetUserProfileSettings(); TagBuilder div = new TagBuilder("div"); switch (avatarSizeType) { case AvatarSizeType.Big: img.MergeAttribute("width", userProfileSettings.AvatarWidth.ToString()); div.AddCssClass("tn-avatar-big"); break; case AvatarSizeType.Medium: img.MergeAttribute("width", userProfileSettings.MediumAvatarWidth.ToString()); div.AddCssClass("tn-avatar-medium"); break; case AvatarSizeType.Small: img.MergeAttribute("width", userProfileSettings.SmallAvatarWidth.ToString()); div.AddCssClass("tn-avatar"); break; case AvatarSizeType.Micro: img.MergeAttribute("width", userProfileSettings.MicroAvatarWidth.ToString()); div.AddCssClass("tn-avatar-mini"); break; } if (!string.IsNullOrEmpty(link) && user != null) { TagBuilder a = new TagBuilder("a"); a.MergeAttribute("href", link); if (navigateTarget != HyperLinkTarget._self) { a.MergeAttribute("target", navigateTarget.ToString()); } if (isShowUserCard) { a.MergeAttribute("plugin", "tipsyHoverCard"); a.MergeAttribute("data-user-card-url", SiteUrls.Instance()._UserCard(user.UserId)); a.MergeAttribute("outerclass", "tn-user-card"); } a.InnerHtml = img.ToString(TagRenderMode.SelfClosing); div.InnerHtml = a.ToString(); return(new MvcHtmlString(div.ToString())); } else { div.InnerHtml = img.ToString(TagRenderMode.SelfClosing); return(new MvcHtmlString(div.ToString())); } }