Avatar billede scriptkid Nybegynder
21. januar 2010 - 13:17 Der er 4 kommentarer

problem med billede i form af (ashx) og System.Drawing.Image

Hej Eksperter,

Jeg har et problem jeg sidder og arbejder med en billedet editor, hvilket ikke er det store problem men de billeder jeg skal hente ind i editoren bliver genereret af en generic handler, og denne virker også som den skal men når jeg prøver at hente det billedet der skal editeres så kommer problemmet. Det er dette kode der fejler 

System.Drawing.Image OldImage = System.Drawing.Image.FromFile(Server.MapPath(GetImages.ashx?Img=testimg.jpg));

Den første fejl jeg får er :
GetImages.ashx?Img=testimg.jpg, is not a valid virtual path

Hvorfor fejler Server.MapPath her ? hvis GetImages.ashx?Img=testimg.jpg havde været testimg.jpg virker det ?

Hvis jeg ændre Server.MapPath(GetImages.ashx?Img=testimg.jpg) til c://testsite/GetImages.ashx?Img=testimg.jpg

så får jeg denne fejl :
Illegal characters in path.
Jeg går udfra at det er ? der er problemmet men hvis jeg HttpServerUtility.UrlEncode'er stien så er stien forkert hvordan gør man det.

og til sidst hvis jeg fjerner ?Img=testimg.jpg delen og hardcoder denne i ashx filen så får jeg denne fejl:
out of memory
Er der nogle der ved hvorfor dette sker?

her er koden i min ashx fil:

<%@ WebHandler Language="C#" Class="GetFileInEditor" %>

using System;
using System.IO;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;

public class GetFileInEditor : IHttpHandler {
   
    public void ProcessRequest (HttpContext context) {

        string Image = "images/Temp/";

        if (string.IsNullOrEmpty(context.Request.QueryString["Img"]) == true)
        {
            Image = "images/ui/website_edit.jpg";
        }
        else {
            Image += context.Request.QueryString["Img"].ToString();       
        }

        System.Drawing.Image ReturnImage = System.Drawing.Image.FromFile(context.Server.MapPath(Image));
        System.IO.FileInfo ImageInfo = new System.IO.FileInfo(context.Server.MapPath(Image));

        string ReturnContentType = "image/jpeg";
        MemoryStream memStream = new MemoryStream();
       
        switch (ImageInfo.Extension)
        {
            case ".jpeg":
                ReturnImage.Save(memStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                break;
            case ".jpg":
                goto case ".jpeg";
            case ".gif":
                ReturnImage.Save(memStream, System.Drawing.Imaging.ImageFormat.Gif);
                ReturnContentType = "image/gif";
                break;
            case ".png":
                ReturnImage.Save(memStream, System.Drawing.Imaging.ImageFormat.Png);
                ReturnContentType = "image/png";
                break;
            case ".bmp":
                ReturnImage.Save(memStream, System.Drawing.Imaging.ImageFormat.Bmp);
                ReturnContentType = "image/bmp";
                break;         
            default:
                goto case ".jpeg";
                break;
        }
     
        memStream.Close();
        ReturnImage.Dispose();
 
        context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        context.Response.Cache.SetNoStore();
        context.Response.Cache.SetExpires(DateTime.MinValue);
        context.Response.ContentType = ReturnContentType;
        context.Response.BufferOutput = false;
        context.Response.OutputStream.Write(memStream.GetBuffer(), 0, memStream.GetBuffer().Length);
        memStream.Dispose();
       
  }

    public bool IsReusable {
        get {
            return false;
        }
    }

}
Avatar billede Syska Mester
22. januar 2010 - 23:42 #1
Hej,

Server.MapPath er jeg ret sikker på tager en relativ stil og før den absolut til en system path:

altså til: "C:\din\mappe\et\sted\filnavn"

Så når du giver den en stil ala overstående ... så  kan den jo slet ikke finde ud af at parse det ... altså alt efter "?" tegnet.

Men en ashx filer skal jo kaldes fra din webhost, så noget ala:
"http://localhost/GetImages.ashx?Img=testimg.jpg"

Så overstående er helt forkert ... og hvis du vil have stien til filen på din host ... så kan du jo ikke bruge den HttpHandler du har lavet ...

Dvs overstående kan ikke lade sig gøre ... hvis den endelig kunne parse det ville det jo bliver til:
"C:\din\sti\GetImages.ashx?Img=TestImage.jpg"

Og oversåtende er jo ikke en valid path i Windows ... kun set fra en Browsers syn ...

Så mit spøgsmål er ... hvad prøver du at opnå ?

mvh
Syska
Avatar billede Syska Mester
22. januar 2010 - 23:45 #2
og ret følgende:
            case ".jpeg":
                ReturnImage.Save(memStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                break;
            case ".jpg":
                goto case ".jpeg";
            case ".gif":

til følgende:

            case ".jpeg":
            case ".jpg":
                ReturnImage.Save(memStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                break;
            case ".gif":

Giver samme resultat ... og så er det nemmere at læse :-)
Avatar billede scriptkid Nybegynder
25. januar 2010 - 11:23 #3
Det jeg prøver på er at få en funktion som denne (se længer nede) til at bruge GetImages.ashx til at hente det billedet som skal redigeres, så jeg bedre kan styre caching af billedet. Dette bunder i at jeg i min image editor hvergang der fortages en ændring af billedet så bliver der oprettet et nyt "temp" billedet som der derefter arbejdes videre med for at jeg let kan fortag en undo ved at gå tilbage til en tidliger "temp" udgave, og det virker perfekt, men der er det problem at editoren virker på den måde at hvis jeg laver en undo og der efter laver en rettelse så bliver den temp som man stod på da man klikket "undo" udskiftet med en ny udgave som så vises men lige nu bliver den gamle cashet udgave af denne "temp" fil vist indtil at editoren er færdig loadet (så vises den nye udgave), men jeg vil ikke have at den viser den gamle cashet udgave for det kan forvirre brugeren.

funktion :

public void Rotate270_Click(object sender, EventArgs e)
    {
        int ChangeCall;
        if (int.Parse(Session["UndoCount"].ToString()) > 0)
        {
            ChangeCall = int.Parse(Session["UndoCount"].ToString()) - 1;
        }
        else
        {
            ChangeCall = 0;
            Session["UndoCount"] = 1;

        }
        string OrginalImage = "images/Temp/Temp" + ChangeCall + "_" + ActiveImage;
        string EditImage = "images/Temp/Temp" + Session["UndoCount"].ToString() + "_" + ActiveImage;

        if (File.Exists(EditImage) == true)
            File.Delete(EditImage);

        System.Drawing.Image OldImage = System.Drawing.Image.FromFile(Server.MapPath(OrginalImage));
        OldImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
        OldImage.Save(Server.MapPath(EditImage));
        ShowImageVersion();
        Session["UndoCount"] = int.Parse(Session["UndoCount"].ToString()) + 1;
       
    }   


så jeg vil gerne have at det "OrginalImage" som hentes, bliver hentet via GetImages.ashx filen. Håber at det giver mening
Avatar billede Syska Mester
25. januar 2010 - 18:48 #4
ja, kan du også ...

På dit Image object på din aspx side ...

Der skal du bare sætte din ImageUrl(mener jeg den hedder) til "/GetImage.ashx?img=dit_billede"

Så når siden loader, laver den et kald til "GetImage.ashx" og loader dit billede ...

Er det ikke hvad du vil ?

mvh
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester