hubFS: THE place for F#

. . . are you on The Hub?
Welcome to hubFS: THE place for F# Sign in | Join | Help
in Search

Bunch Resizing of Pictures

Last post 04-22-2008, 16:44 by Julien. 0 replies.
Sort Posts: Previous Next
  •  04-22-2008, 16:44 5814

    Bunch Resizing of Pictures

    I wrote these few lines to resize a bunch of pictures all at once (emailing (usually large) pics from numeric cameras isn't always fun...).

    Note that the output directory and the prefix for output images are both optional...

    Also note that you can combine both directory-wide and specific files selections. I guess I could have used a used a delete button for each specific file, but I went for laziness!

    I hope some may find it useful !



    #light

    open System
    open System.Drawing
    open System.Drawing.Drawing2D
    open System.IO
    open System.Windows.Forms

    let process_file file output_dir prefix long_side =
      if File.Exists(file)
      then
        try
          let img = new Bitmap(file)
         
          let ratio = float (if img.Width > img.Height then img.Width else img.Height) / long_side
          let w = int <| Math.Round(float img.Width / ratio)
          let h = int <| Math.Round(float img.Height / ratio)
         
          let dst = new Bitmap(w, h)
         
          use g = Graphics.FromImage(dst)
          g.SmoothingMode <- SmoothingMode.HighQuality
          g.InterpolationMode <- InterpolationMode.HighQualityBicubic
         
          let img_rect = new RectangleF(0.0f, 0.0f, single img.Width, single img.Height)
          let dst_rect = new RectangleF(0.0f, 0.0f, single w, single h)    
          g.DrawImage(img, dst_rect, img_rect, GraphicsUnit.Pixel)
         
          let dir = match output_dir with Some d -> d | None -> Filename.dirname file
          let path = Filename.concat dir (prefix + Filename.basename file)
          dst.Save(path, img.RawFormat)
        with
          e -> ()
         
    //Form     

    let form = new Form(Visible=true, AutoSize=true, AutoSizeMode=AutoSizeMode.GrowAndShrink, Text="Resize Pictures", BackColor=Color.White)

    let panel = new FlowLayoutPanel(AutoSize=true, AutoSizeMode=AutoSizeMode.GrowAndShrink, Dock = DockStyle.Fill, FlowDirection = FlowDirection.TopDown)

    let run = new Button(AutoSize=true, Enabled=false, Text="Run")

    //Select Files
    let files = new Label(AutoSize=true)
    let files_browse = new Button(AutoSize=true, Text="Select files...")
    let files_browser = new OpenFileDialog(Multiselect=true, Title="Select files to shrink", Filter="Image Files(*.BMP;*.JPG;*.GIF;*.PNG)|*.BMP;*.JPG;*.GIF;*.PNG|All files (*.*)|*.*")
    let files_set : ref<Set<string>> = ref Set.empty
    let files_clear = new Button(AutoSize=true, Text="Clear", Enabled=false)
    let files_panel = new FlowLayoutPanel(AutoSize=true)
    do
      files_browse.Click.Add(fun _ ->
        if files_browser.ShowDialog() = DialogResult.OK
        then
          if not run.Enabled then run.Enabled <- true
          for file in files_browser.FileNames do
            if not <| Set.mem file !files_set
            then
              files_set := Set.add file !files_set
              files.Text <- files.Text + "\n" + file
          files_clear.Enabled <- true
      ) 
      files_clear.Click.Add(fun _ ->
        files.Text <- ""
        files_clear.Enabled <- false
        files_set := Set.empty
      )
      files_panel.Controls.Add(files_browse)
      files_panel.Controls.Add(files_clear)

    //Select directories
    let directory = new Label(AutoSize=true)
    let directory_browse = new Button(AutoSize=true, Text="Select directory...")
    let directory_browser = new FolderBrowserDialog()
    let directory_clear = new Button(AutoSize=true, Text="Clear", Enabled=false)
    let directory_panel = new FlowLayoutPanel(AutoSize=true)
    do
      directory_browse.Click.Add(fun _ ->
        if directory_browser.ShowDialog() = DialogResult.OK
        then
          if not run.Enabled then run.Enabled <- true
          directory.Text <- directory_browser.SelectedPath
          directory_clear.Enabled <- true
      ) 
      directory_clear.Click.Add(fun _ ->
        directory.Text <- ""
        directory_clear.Enabled <- false
      )
      directory_panel.Controls.Add(directory_browse)
      directory_panel.Controls.Add(directory_clear)
     
    //Output directory
    let output_dir = new Label(Width = form.Width / 2, AutoSize=true)
    let output_browser = new FolderBrowserDialog()
    let output_browse = new Button(AutoSize=true, Text="Select output directory...")
    let output_clear = new Button(AutoSize=true, Text="Clear", Enabled=false)
    let output_panel = new FlowLayoutPanel(AutoSize=true)
    do
      output_browse.Click.Add(fun _ ->
        if output_browser.ShowDialog() = DialogResult.OK
        then
          output_dir.Text <- output_browser.SelectedPath
          output_clear.Enabled <- true
      ) 
      output_clear.Click.Add(fun _ ->
        output_dir.Text <- ""
        output_clear.Enabled <- false
      )
      output_panel.Controls.Add(output_browse)
      output_panel.Controls.Add(output_clear)

    //Output Images Prefix
    let prefix = new TextBox(Text="resized_", Width=75)
    let prefix_label = new Label(AutoSize=true, Text="Prefix for output files")
    let prefix_panel = new FlowLayoutPanel(AutoSize=true)
    do
      prefix_panel.Controls.Add(prefix)
      prefix_panel.Controls.Add(prefix_label)

    //Longest side size
    let updown =
      let v = Convert.ToDecimal(800)
      let min = Convert.ToDecimal(1)
      let inc = Convert.ToDecimal(50) 
      new NumericUpDown(ThousandsSeparator=true, Minimum=min, Maximum=System.Decimal.MaxValue, Value=v, DecimalPlaces=0, Increment=inc, Width=75)
    let updown_label = new Label(AutoSize=true, Text="Longest side size in pixels")
    let updown_panel = new FlowLayoutPanel(AutoSize=true)
    do
      updown_panel.Controls.Add(updown)
      updown_panel.Controls.Add(updown_label)

    do
      panel.Controls.Add(files) 
      panel.Controls.Add(files_panel) 
      panel.Controls.Add(directory)
      panel.Controls.Add(directory_panel)
      panel.Controls.Add(output_dir)
      panel.Controls.Add(output_panel) 
      panel.Controls.Add(prefix_panel) 
      panel.Controls.Add(updown_panel) 
      panel.Controls.Add(run)
      form.Controls.Add(panel)

      run.Click.Add(fun _ ->
        let dir = if String.length output_dir.Text > 0 then Some output_dir.Text else None
        for file in files_browser.FileNames do
          process_file file dir prefix.Text (float updown.Value)   
        if String.length directory.Text > 0
        then
          for file in Directory.GetFiles(directory.Text) do
            process_file file dir prefix.Text (float updown.Value)   
      ) 
     
    #if COMPILED
    // Run the main code. The attribute marks the startup application thread as "Single
    // Thread Apartment" mode, which is necessary for GUI applications.
    [<STAThread>]
    do
      Application.EnableVisualStyles()
      Application.Run(form)
    #endif

View as RSS news feed in XML
Powered by Community Server, by Telligent Systems