如何在同一 aspx 页面中临时存储图像,而不使用文件系统?
Posted
技术标签:
【中文标题】如何在同一 aspx 页面中临时存储图像,而不使用文件系统?【英文标题】:How to temporarily store a image within same aspx page, not using the filesystem ? 【发布时间】:2015-08-12 23:14:25 【问题描述】:我正在使用 asp.net 网络表单和 jcrop(文件上传后裁剪图像)..
这个例子我在这里将临时图像存储到文件系统,但是..由于天蓝色我不能(也不会)这样做..
Soo.. 我怎样才能拥有相同的功能而不保存到磁盘?这意味着......如果可能的话,我希望有一个流在整个线上......
public partial class UserConfig : System.Web.UI.Page
String path = HttpContext.Current.Request.PhysicalApplicationPath + "images\\";
protected void Page_Load(object sender, EventArgs e)
protected void btnUpload_Click(object sender, EventArgs e)
Boolean FileOK = false;
Boolean FileSaved = false;
if (Upload.HasFile)
Session["WorkingImage"] = Upload.FileName;
String FileExtension = Path.GetExtension(Session["WorkingImage"].ToString()).ToLower();
String[] allowedExtensions = ".png", ".jpeg", ".jpg", ".gif" ;
for (int i = 0; i < allowedExtensions.Length; i++)
if (FileExtension == allowedExtensions[i])
FileOK = true;
if (FileOK)
try
Upload.PostedFile.SaveAs(path + Session["WorkingImage"]);
FileSaved = true;
catch (Exception ex)
lblError.Text = "File could not be uploaded." + ex.Message.ToString();
lblError.Visible = true;
FileSaved = false;
else
lblError.Text = "Cannot accept files of this type.";
lblError.Visible = true;
if (FileSaved)
pnlUpload.Visible = false;
pnlCrop.Visible = true;
imgCrop.ImageUrl = "images/" + Session["WorkingImage"].ToString();
protected void btnCrop_Click(object sender, EventArgs e)
string ImageName = Session["WorkingImage"].ToString();
int w = Convert.ToInt32(W.Value);
int h = Convert.ToInt32(H.Value);
int x = Convert.ToInt32(X.Value);
int y = Convert.ToInt32(Y.Value);
byte[] CropImage = Crop(path + ImageName, w, h, x, y);
using (MemoryStream ms = new MemoryStream(CropImage, 0, CropImage.Length))
ms.Write(CropImage, 0, CropImage.Length);
using (SD.Image CroppedImage = SD.Image.FromStream(ms, true))
string SaveTo = path + "crop" + ImageName;
CroppedImage.Save(SaveTo, CroppedImage.RawFormat);
pnlCrop.Visible = false;
pnlCropped.Visible = true;
imgCropped.ImageUrl = "images/crop" + ImageName;
static byte[] Crop(string Img, int Width, int Height, int X, int Y)
try
using (SD.Image OriginalImage = SD.Image.FromFile(Img))
using (SD.Bitmap bmp = new SD.Bitmap(Width, Height))
bmp.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution);
using (SD.Graphics Graphic = SD.Graphics.FromImage(bmp))
Graphic.SmoothingMode = SmoothingMode.AntiAlias;
Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
Graphic.DrawImage(OriginalImage, new SD.Rectangle(0, 0, Width, Height), X, Y, Width, Height, SD.GraphicsUnit.Pixel);
MemoryStream ms = new MemoryStream();
bmp.Save(ms, OriginalImage.RawFormat);
return ms.GetBuffer();
catch (Exception Ex)
throw (Ex);
【问题讨论】:
如果你想要一个流,把它放在会话中。您必须小心,因为会话中的太多可能会达到内存屏障并导致应用程序池回收。您可以尝试通过序列化字符串将其序列化为视图状态,但这会随着视图状态膨胀而真正减慢往返速度。 是的@Mark .. 尤其是在 Session 上犯了错误,而且之前还有些 ViewState..,所以不太急于再去那趟旅行 :)due to azure
这需要更多解释。 Azure 是什么让您不愿意将图像存储在磁盘上?
这是一个很好的观点@Sam :) 我已经有一段时间没有在使用 Azure 网站时在文件系统上存储数据了。记住我有一个 非常 上次我试图调整这个来工作时很难。所以......也许你知道一些我不知道的关于在使用 Azure 时在文件系统上存储文件的事情?
我使用 Azure SDK(通过 NuGet 安装)和 Azure 存储 API(CloudStorageAccount、CloudBlobClient、CloudBlobContainer、CloudBlockBlob)。可从 Azure 网站访问 Azure 存储,上传文件后,即可通过标准 URL 访问该文件。
【参考方案1】:
如果你不反对使用 Azure 存储,这里是我使用的一个类。它专为上传图像和 pdf 而设计,但我相信您可以对其进行修改以满足您的需求。
用法:
Dim storage As AzureStorage = New AzureStorage("storage name", "storage key")
storage.UploadFile("directory name", "filename", fileStream)
上传后,您的文件可通过 url 访问:
http://yourdomain.blob.core.windows.net/container-name/filename
助手类:
Imports System
Imports System.IO
Imports Microsoft.WindowsAzure.Storage
Imports Microsoft.WindowsAzure.Storage.Auth
Imports Microsoft.WindowsAzure.Storage.Blob
'
' See http://msdn.microsoft.com/en-us/library/dd135715.aspx for naming guidelines.
'
Public Class AzureStorage
Public Sub New(ByVal storageName As String, ByVal storageKey As String)
Me.StorageName = storageName
Me.StorageKey = storageKey
End Sub
Private Function GetStorageAccount() As CloudStorageAccount
Dim result As CloudStorageAccount = New CloudStorageAccount(New StorageCredentials(StorageName, StorageKey), True)
Return result
End Function
Private Function GetBlobContainer(ByVal name As String) As CloudBlobContainer
Dim account As CloudStorageAccount = GetStorageAccount()
Dim client As CloudBlobClient = account.CreateCloudBlobClient
Dim result As CloudBlobContainer = client.GetContainerReference(name)
result.CreateIfNotExists(BlobContainerPublicAccessType.Blob)
Return result
End Function
Private Function GetBlob(ByVal containerName As String, ByVal name As String) As CloudBlockBlob
Dim container As CloudBlobContainer = GetBlobContainer(containerName)
Dim result As CloudBlockBlob = container.GetBlockBlobReference(name)
Return result
End Function
Public Sub UploadFlyer(ByVal fileName As String, ByVal stream As Stream)
UploadFile("flyers", fileName, stream)
End Sub
Public Sub UploadLogo(ByVal fileName As String, ByVal stream As Stream)
UploadFile("class-logos", fileName, stream)
End Sub
Public Sub UploadFile(ByVal containerName As String, ByVal fileName As String, ByVal stream As Stream)
Dim blob As CloudBlockBlob = GetBlob(containerName, fileName)
Dim targetMaximumSize As Int32 = 144
Dim width As Int32 = targetMaximumSize
Dim height As Int32 = targetMaximumSize
Dim coefficient As Decimal = 1
Dim imageStream As Stream = New MemoryStream
Dim formats As Dictionary(Of String, System.Drawing.Imaging.ImageFormat) = New Dictionary(Of String, Drawing.Imaging.ImageFormat)
Dim extension As String = Path.GetExtension(fileName).Trim.ToLower
formats.Add(".jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
formats.Add(".png", System.Drawing.Imaging.ImageFormat.Png)
'
' Resize source image to max 144px (2") to a side
'
If formats.ContainsKey(extension) Then
Using sourceImage As System.Drawing.Image = System.Drawing.Image.FromStream(stream)
coefficient = targetMaximumSize / Math.Max(sourceImage.Width, sourceImage.Height)
If coefficient < 1 Then
width = sourceImage.Width * coefficient
height = sourceImage.Height * coefficient
Using targetImage As System.Drawing.Image = New System.Drawing.Bitmap(width, height)
Using graphics As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(targetImage)
graphics.DrawImage(sourceImage, targetImage.GetBounds(System.Drawing.GraphicsUnit.Pixel), sourceImage.GetBounds(System.Drawing.GraphicsUnit.Pixel), Drawing.GraphicsUnit.Pixel)
End Using
targetImage.Save(imageStream, formats(extension))
End Using
Else
sourceImage.Save(imageStream, formats(extension))
End If
End Using
imageStream.Seek(0, SeekOrigin.Begin)
blob.UploadFromStream(imageStream)
Else
blob.UploadFromStream(stream)
End If
imageStream.Dispose()
End Sub
Public Sub DeleteFile(ByVal containerName As String, ByVal fileName As String)
Dim blob As CloudBlockBlob = GetBlob(containerName, fileName)
blob.DeleteIfExists(DeleteSnapshotsOption.IncludeSnapshots)
End Sub
Public Property StorageName As String = String.Empty
Public Property StorageKey As String = String.Empty
End Class
【讨论】:
谢谢@Sam :) 明天下午我会完成,因为我必须上床去参加摩洛哥婚礼(dooh!).. 假期不是很有趣 :) 我有一个储藏室已经设置为上传图片,但我喜欢你通过“UploadFile”方法上传的方式.. :) 我明天试试.. 不过.. 我需要两步(两个不同的页面或.. updatepanel 更新以使这项工作:) 正确。此方法需要通过页面重新加载或 XHR 往返服务器。它没有按要求回答问题,但您可能会发现它很有用。我希望婚礼很有趣!以上是关于如何在同一 aspx 页面中临时存储图像,而不使用文件系统?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET - 如何在浏览器中显示图像而不将图像保存在临时文件中?
OpenCV:如何使用 cv::imwrite 保存图像而不覆盖它们