Custom Upload System Options
justin_kaizen
Posted: Tuesday, July 29, 2008 7:21:36 PM

Rank: Newbie

Joined: 6/25/2008
Posts: 10
Location: ottawa
Hello. I'm making a system where an end user when uploading media has to Crop it using a javascript + .NET image saving routine.

I have this part working, and integrated into umbraco pointing to a static file.

What i want to do is save the file the same way umbraco does using numbers, (IE media\10003\awesome.jpg), and also entered into the database the same way a generic upload would. (if it even is, i'm not sure)

Where should i look in the umbraco library to get a start on this? I have been looking at the umbraco.library but have come up short so far. I'm sure the ID numbers are not random and I would like to fit my package into umbraco as much as possible.

Thanks much!
Justin
fed
Posted: Tuesday, July 29, 2008 8:44:52 PM

Rank: Aficionado

Joined: 3/30/2008
Posts: 109
Location: Sweden
You should check out this, if I recall correctly it creates media items, and also thumbnails for them..

http://codegarden.umbraco.org/blog/2007/5/11/we-just-build-an-ftp-datatype-in-45-minutes

Also, I would love to see your crop-routine in action..
justin_kaizen
Posted: Tuesday, July 29, 2008 10:36:19 PM

Rank: Newbie

Joined: 6/25/2008
Posts: 10
Location: ottawa
http://www.codeproject.com/KB/custom-controls/ImageCroppingControl.aspx

Thats the control i'm working with. I have a modified version *almost* integrated into umbraco as a custom data type, that alters a picture in an exsisting directory.

What i'm doing for the Node side of this is trying to use the umbraco.presentation.nodeFactory.

Namely:
using umbraco.presentation.nodeFactory;
....

Node n = Node.GetCurrent();

foreach (Property p in n.Properties)
{
if(p.Alias.CompareTo("location")==0)
{
p.Value = "**uploaded location**";
}
if(p.Alias.CompareTo("other")==0)
{
p.Value = "**other val**";
}
}

}

That didnt work because the nodes are read only with no pub functions. (I thought a set might trigger a database update, and that would be slick). but no :(

If anyone knows how to create a new node in C# let me know... I'm pretty much on top of google and creeping the umbraco namespaces right now..

In the mean time I'm going to make the cropper access Node.GetCurrent();, looking for its *.jpg file. It will grab that file and save it as *_cropped.jpg. This way i can piggy back on the exsisting upload Data type while still having some measure of integration.

In the future I'd really like to have it as its own entity so If anyone has any information give me a shout!

(P.S. the ftp interface didnt seem to do anything with the media section or node management. Unless i missed it completely!)



fed
Posted: Tuesday, July 29, 2008 11:08:25 PM

Rank: Aficionado

Joined: 3/30/2008
Posts: 109
Location: Sweden
I can provide you with some snippets of code that I used when importing images to media library. With this you can create MediaFolders and images.. Hope you can use it to something atleast :)

NoPasteLink here

Code:

        protected Media GenerateMediaTypeFolder(string title, int parent) {
            // The umbraco user that should create the document,
            // 0 is the umbraco system user, and always exists
            umbraco.BusinessLogic.User u = new umbraco.BusinessLogic.User(0);

            MediaType mediaTypeFolder = new MediaType(1031);

            Media m = Media.MakeNew(title, mediaTypeFolder, u, parent);
            m.XmlGenerate(new XmlDocument());
            return m;
        }

        protected Media GenerateMediaTypeImage(string title, string fileToImport, int parent) {
            // The umbraco user that should create the document,
            // 0 is the umbraco system user, and always exists
            umbraco.BusinessLogic.User u = new umbraco.BusinessLogic.User(0);

            MediaType mediaTypeImage = new MediaType(1032);
            Media m = Media.MakeNew(title, mediaTypeImage, u, parent);

            FileInfo f = new FileInfo(HttpContext.Current.Server.MapPath(fileToImport));

            string destinationDirectory = String.Format("/media/{0}/", m.Id);
            string destination = destinationDirectory + f.Name;

            Directory.CreateDirectory(HttpContext.Current.Server.MapPath(destinationDirectory));
            FileInfo copied = f.CopyTo(HttpContext.Current.Server.MapPath(destination), true);

            m.getProperty("umbracoFile").Value = destination;
            m.getProperty("umbracoExtension").Value = f.Extension;
            m.getProperty("umbracoBytes").Value = f.Length;

            System.Drawing.Image i = GetImageFromFileInfo(copied);
            m.getProperty("umbracoWidth").Value = i.Width;
            m.getProperty("umbracoHeight").Value = i.Height;
            m.XmlGenerate(new XmlDocument());
            GenerateThumb(copied);
            return m;
        }

        private System.Drawing.Image GetImageFromFileInfo(FileInfo f) {
            FileStream fs = new FileStream(f.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
            System.Drawing.Image image = System.Drawing.Image.FromStream(fs);
            fs.Close();
            return image;
        }

        private void GenerateThumb(FileInfo f) {
            string orgExt = ((string)f.FullName.Substring(f.FullName.LastIndexOf(".") + 1, f.FullName.Length - f.FullName.LastIndexOf(".") - 1));
            orgExt = orgExt.ToLower();
            string fileNameThumb = f.FullName.Replace("." + orgExt, "_thumb");

            int fileWidth;
            int fileHeight;

            System.Drawing.Image image = GetImageFromFileInfo(f);
            fileWidth = image.Width;
            fileHeight = image.Height;
            generateThumbnail(image,100,image.Width,image.Height,f.FullName,orgExt,fileNameThumb+".jpg");
        }

        private void generateThumbnail(System.Drawing.Image image, int maxWidthHeight, int fileWidth, int fileHeight, string fullFilePath, string ext, string thumbnailFileName) {
            // Generate thumbnail
            float fx = (float)fileWidth / (float)maxWidthHeight;
            float fy = (float)fileHeight / (float)maxWidthHeight;
            // must fit in thumbnail size
            float f = Math.Max(fx, fy); //if (f < 1) f = 1;
            int widthTh = (int)Math.Round((float)fileWidth / f);
            int heightTh = (int)Math.Round((float)fileHeight / f);

            // fixes for empty width or height
            if(widthTh == 0)
                widthTh = 1;
            if(heightTh == 0)
                heightTh = 1;

            // Create new image with best quality settings
            Bitmap bp = new Bitmap(widthTh, heightTh);
            Graphics g = Graphics.FromImage(bp);
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;

            // Copy the old image to the new and resized
            Rectangle rect = new Rectangle(0, 0, widthTh, heightTh);
            g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);

            // Copy metadata
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo codec = null;
            for(int i = 0;i < codecs.Length;i++) {
                if(codecs[i].MimeType.Equals("image/jpeg"))
                    codec = codecs[i];
            }

            // Set compresion ratio to 90%
            EncoderParameters ep = new EncoderParameters();
            ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L);

            // Save the new image
            bp.Save(thumbnailFileName, codec, ep);
            bp.Dispose();
            g.Dispose();

        }               

drobar
Posted: Wednesday, July 30, 2008 12:12:26 AM

Rank: Umbracoholic

Joined: 9/8/2006
Posts: 1,696
Location: KY, USA
Very interested in your cropping datatype if you can get it going! It may make a nice pairing with ImageGen (http://www.percipientstudios.com/imagegen.aspx).

For uploading, ftp, etc. check out John's excellent post and video upload tool/code at http://forum.umbraco.org/yaf_postst2317_File-repository.aspx.

cheers,
doug.

MVP 2007-2009 - Official Umbraco Trainer for North America - Percipient Studios
neehouse
Posted: Wednesday, July 30, 2008 8:20:25 AM

Rank: Umbracoholic

Joined: 7/20/2006
Posts: 1,074
Location: Charleston, West Virginia, United States
The id for the folder is the id of the property on the node where the image is inserted node wise.

If you look at the editor controls upload, you will be able to see how this works by default.

In regards to approach, this can be handled in a multitude of ways. The crop tool could be its own data type which references another property to pull in the 'original' image, and save the image in a separate folder, and tracks the cropped image location in the data.

A second approach is to have the upload and cropper be in the same data type, in which the cropper tool can be shown after save (new upload) or with a button press. A variety of data pieces could be saved at this point.

The upload could definitely benefit from a revamp, with one feature being validation. This can be fixed by removing the upload field if an file is already present.

I am very interested in where this progresses to.

• 2007/2008 MVP • 2008/2009 MVP • Certified • Licensing • Support • Development • Hosting •
justin_kaizen
Posted: Thursday, August 14, 2008 3:05:08 PM

Rank: Newbie

Joined: 6/25/2008
Posts: 10
Location: ottawa
Well I'll keep you guys posted, 100%. The due date for the deployment of the whole project is the 5th of September. Unfortunately the validation and cropping of the pictures is one of the 'would be nice' features. We're well ahead of the game but I'm working on more of the core features right now.

No matter what, I'm going to get back to it, and thanks to the feedback above I now have a clearer understanding of what to do! I'll try to make it clean too so you guys wont cringe when you see my code :o. Right now its what i would call more of a 75% working prototype!

As for 2 separate data types or one, I have thought about this as well. I think i prefer it being one so it can force validation of the image based upon dimension attributes, and pretty much clone the behaviour of the existing upload (with maybe the original image backed up as _orginal.jpg)

If its 2 separate data types it makes validation either not 100%, or it forces the whole CMS to refer a "*_processed.jpg" version, which is not ideal either.

Thanks for all the feedback and I'll have more shortly!
Users browsing this topic
Guest


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.