How hard is to implement resize on client?

Oct 15, 2010 at 1:37 AM

Is it possible to implement a resize on the client in order to save bandwidth on the server? How hard is to implement it?

Rod

Oct 20, 2010 at 3:37 PM

Yes it is. Just take a look at the other project that already does it: http://silverlightfileupld.codeplex.com/

I implemented a feature like this on my own control, but it is a bit buggy. I'm working on adding a pre-uploading step at the moment to help with this. If I come up with something decent I'll post it on here.

Oct 22, 2010 at 4:21 PM
Edited Oct 22, 2010 at 4:26 PM

I have implemented this but I didn't have time to perfect it, and there is probably a much better way to do this. Pretty much just use the code from the other project and plug it in to the right spot.

 

FileCollection.cs:

 

        public void UploadFiles()
        {
            foreach (UserFile file in this)
            {
                if (!file.IsDeleted && file.State == Constants.FileStates.Pending && _currentUpload < MaxUploads)
                {
                    if (file.FileName.ToLower().EndsWith("jpg"))
                    {
                        file.State = Constants.FileStates.Resizing;
                        // create a thread and process the image resize using that thread
                        BackgroundWorker worker = new BackgroundWorker();
                        worker.DoWork += new DoWorkEventHandler(file.worker_DoWork);
                        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(file.worker_RunWorkerCompleted);
                        worker.RunWorkerAsync();
                    }
                    file.Upload(UploadedFileProcessorType, UserContextParameter);
                    _currentUpload++;
                }
            }
        }

 

In Constants.cs add this line: Resizing = 7,

Be sure to add a reference to fluxjpeg dll. I believe one is provided in the other project, but you can also go to: http://code.google.com/p/fjcore/updates/list

In UserFile.cs:

 

using FluxJpeg.Core.Decoder;
using FluxJpeg.Core;
using FluxJpeg.Core.Filtering;
using FluxJpeg.Core.Encoder;

 

 

Add the following strings:

 

        private string _uploadedFileProcessorType;
        private string _contextParam;

 

Add the following functions:

 

        public void Resize()
        {
            Stream fileStream = this.FileStream;
            using (fileStream)
            {
                // Decode
                DecodedJpeg jpegIn = new JpegDecoder(fileStream).Decode();

                if (ImageResizer.ResizeNeeded(jpegIn.Image, 300))
                {
                    // Resize
                    DecodedJpeg jpegOut = new DecodedJpeg(
                        new ImageResizer(jpegIn.Image)
                            .Resize(300, ResamplingFilters.LowpassAntiAlias),
                        jpegIn.MetaHeaders); // Retain EXIF details

                    // Encode
                    MemoryStream tempStream = new MemoryStream();
                    new JpegEncoder(jpegOut, 90, tempStream).Encode();
                    // Display 
                    tempStream.Seek(0, SeekOrigin.Begin);
                    // replace our current stream.
                    this._fileStream = tempStream;
                    this._fileSize = tempStream.Length;
                }
            }
            // Finished, set the file state.
            this.State = Constants.FileStates.Pending;
        }
        public void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Upload(this._uploadedFileProcessorType, this._contextParam);
        }

        public void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Resize();
        }

 

 

Modify the upload function:

 

        public void Upload(string UploadedFileProcessorType, string ContextParam)
        {
            this._contextParam = ContextParam;
            this._uploadedFileProcessorType = UploadedFileProcessorType;
            // wait if it is resizing.
            if (this.State == Constants.FileStates.Resizing)
                return;
            // if we're already uploading, don't do anything
            if (this.State == Constants.FileStates.Uploading)
                return;

            this.State = Constants.FileStates.Uploading;

            if (HttpUploader)
                _fileUploader = new HttpFileUploader(this, UploadHandlerName, ChunkSizeMB);
            // for now use only the http uploader method
            //else
            //    _fileUploader = new WcfFileUploader(this);

            _fileUploader.UploadFinished += new EventHandler(fileUploader_UploadFinished);
            _fileUploader.UploadCanceled += new EventHandler(fileUploader_UploadCanceled);
            _fileUploader.UploadDataSent += new EventHandler<UploadDataSentArgs>(fileUploader_UploadDataSent);
            _fileUploader.UploadErrorOccurred += new EventHandler<UploadErrorOccurredEventArgs>(fileUploader_UploadErrorOccurred);
            _fileUploader.UploadProcessingStarted += new EventHandler(fileUploader_UploadProcessingStarted);

            _fileUploader.StartUpload(UploadedFileProcessorType, ContextParam);
        }

 

Thats all there is to it. Special thanks to http://silverlightfileupld.codeplex.com/ for their contribution.

If anyone finds a better way to do this, let me know. This does have a couple small issues but for the most part works well.

 

Behr