VirtualBox direct access to SD Card in Windows

I’ve trying to get my Raspberry Pi working with a touchscreen (eGalax Touch).

This blog post has been an incredible help, but I stumbled at the very last hurdle – modifying the contents of the SD card.

You see, my compile system (Ubuntu 13.04) was in a virtual machine (VM) – VirtualBox running on Windows 7.

Windows 7 doesn’t know how to read the various linux filesystems, so they’re invisible, which means I needed to access to the whole, raw disk directly from the VM.

Here’s a step-by-step guide to directly mounting raw SD card in your virtual machine, so you can edit it.

    1. Get the DeviceID for you SD Card reader

Open a command window as an administrator. (Press Start, type cmd, right click on cmd.exe in the list, and choose “Run as administrator”)

type

wmic diskdrive list brief

and if your system is anything like mine you’ll get something like this:

C:\Users\Sandy Scott>wmic diskdrive list brief
Caption                      DeviceID            Model                        Partitions  Size
WDC WD7500BPKT-75PK4T0       \\.\PHYSICALDRIVE0  WDC WD7500BPKT-75PK4T0       3           750153761280
O2Micro SD SCSI Disk Device  \\.\PHYSICALDRIVE1  O2Micro SD SCSI Disk Device  1           3964584960

The top item is the main hard drive, the lower one is the SD card.

The bit we’re interested in is the DeviceID, in this case \\.\PHYSICALDRIVE1

    1. Navigate to the VirtualBox directory

Next thing you’ll need to find is the installation directory for VirtualBox. This is usually C:\Program Files\Oracle\VirtualBox\. You’ll know it’s the right one if it has lots of files starting with VBox in it.

Go there by entering this command

cd C:\Program Files\Oracle\VirtualBox
    1. Create the link file to the SD card
VBoxManage internalcommands createrawvmdk -filename "%USERPROFILE%/Desktop/sdcard.vmdk" -rawdisk "\\.\PHYSICALDRIVE1"

The file you’ve just created (sdcard.vmdk, on your Desktop) is a special link that lets a virtual machine access the SD card.

    1. Connect the VM to the SD card using the link

Now, open VirtualBox as Administrator, and open the Settings for your virtual machine. Go to Storage -> Controller: SATA -> (right click) Add Hard Disk -> Choose Existing Disk and open the file you just created.

Fire up the VM and you should be able to access the SD card in all it’s glory!

Batch Editing with Gimp Script-fu

A couple of days I posted a short script, that did a few very simple tasks – that was just a start, to help me get into Gimp Scripting, and help with a little job.

Today’s task is quite a bit meatier.

I’m doing tech for a play, and I want a copy of the script that I can mark up. I’ve scanned the whole thing, but it has all the usual problems with scans – pages aren’t aligned, background isn’t white, and you can see text on the other side of the page showing through.

All these can be fixed, and some even automated.

I’m not enough of an image processing wizard to fix the alignment automatically, but Gimp’s rotate and crop tools should do you proud! I found the Fixed->Size option in Rectangle Select very useful for getting all the output images the same size.

The script does the rest, read the comments (anything after a “;” on a line) to see how it works.

(script-fu-register
            "script-fu-scan-text-enhance"  ;func name
            "Scanned Text Enhance"         ;menu label
            "Scanned Text Enhancement"     ;description
            "Sandy Scott"                  ;author
            "Copyright 2013, Sandy Scott"  ;copyright notice
            "August 4, 2013"               ;date created
            "*"                            ;image type that the script works on
            SF-IMAGE       "Input image" 0
            SF-DRAWABLE    "Input drawable" 0 
            )
(script-fu-menu-register "script-fu-scan-text-enhance" "/Filters/Text")

(define (script-fu-scan-text-enhance image drawable)

    (let* ( )    
        
        ; Prep
        (gimp-context-push)
        (gimp-image-undo-group-start image)
        
        ; Actual work here
        
        ; Duplicate Layer
        (gimp-image-insert-layer image (car (gimp-layer-copy (car (gimp-image-get-active-layer image)) FALSE)) 0 0)
        
        ; Threshold
        (gimp-threshold (car  (gimp-image-get-active-drawable image)) 127 255)
        
        ; Select by Colour
        (gimp-context-set-antialias TRUE)
        (gimp-context-set-feather TRUE)
        (gimp-context-set-feather-radius 1.5 1.5)
        (gimp-context-set-sample-merged FALSE)
        (gimp-context-set-sample-threshold-int 1)
        (gimp-context-set-sample-transparent FALSE)
        (gimp-image-select-color image CHANNEL-OP-REPLACE (car  (gimp-image-get-active-drawable image)) '(0 0 0))
        
        ; Grow Selection
        (gimp-selection-grow image 1)
        (gimp-selection-invert image)
        
        ; Hide Duplicated Layer
        (gimp-item-set-visible (car  (gimp-image-get-active-drawable image)) FALSE)
        
        ; Activate Bottom Layer
        (gimp-image-set-active-layer image (vector-ref (cadr (gimp-image-get-layers image)) (- (vector-length (cadr (gimp-image-get-layers image))) 1)))
        
        
        ; Fill Selection with White
        (gimp-edit-fill (car  (gimp-image-get-active-drawable image)) WHITE-FILL)
        
        ; Clear Selection
        (gimp-selection-none image)
        
        ; Finishing Off
        (gimp-image-undo-group-end image)
        (gimp-context-pop)
        (gimp-displays-flush)
    )
)

Save with a .scm file extension put this in your scripts Directory (go to Edit->Preferences->Folders->Scripts if you don’t know where that is) then reload scripts (Filters->Script-Fu->Refresh Scripts). It should appear as Filters->Text->Scanned Text Enhance.

That’s all well and good if you’ve only got one image. What if you’ve got 80? Let’s automate this with a script.

The above script does the actual work of manipulating the image – the next one does the donkey work of loading the file, starting the manipulation script, then saving the file. In this case, it just saves over the old file, so make sure you’ve got a copy of the original in case it goes wrong. This should also be saved with a .scm extension in your scripts directory.

(define (scan-text-enhance filename)
    (let* (
            (image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
            (drawable (car (gimp-image-get-active-layer image))) )
        (script-fu-loot-prep2 image drawable)
        (gimp-file-save RUN-NONINTERACTIVE image drawable filename filename)
        (gimp-image-delete image)
    )
)

This has helped a bit – this script allows us run the text processing with only one piece of information – the filename, but how do you run it?
Type this into your command line:

"C:\Program Files\GIMP 2\bin\gimp-console-2.8.exe" -i -b "(scan-text-enhance \"filename.png\")" -b "(gimp-quit 0)"

You might need to change the path to your installation of Gimp, and also filename.png to the path to your image.

Finally, to automate this, I’m going to use a batch file. Make a batch file with this text:

for %%x in (*.png) do "C:\Program Files\GIMP 2\bin\gimp-console-2.8.exe" -i -b "(script-enhance \"%%x\")" -b "(gimp-quit 0)"

This will run our script on all the .png images in the current directory.

Thanks to:
Gimp Tutorials: GIMP Batch Mode
Gimp Docs: A Script-Fu Tutorial
SuperUser: Windows batch processing images with gimp and saving them to new files

A basic Gimp script-fu

I’ve just been playing with Gimp, and getting to grips with the scripting system.

I’m sharing a very basic script – it only does two simple tasks:

  • Sets the image to Grayscale
  • Rotates 90 degrees counter-clockwise

It doesn’t need any extra parameters, so I thought I’d share it as a very simple example that you can adapt to your needs!

(script-fu-register
    "script-fu-test-script"                     ;func name
    "Test Script"                               ;menu label
    "Test script that does a few simple tasks"  ;description
    "Sandy Scott"                               ;author
    "Copyright 2013, Sandy Scott"               ;copyright notice
    "August 3, 2013"                            ;date created
    "*"                                         ;image type that the script works on
    SF-IMAGE       "Input image" 0
    SF-DRAWABLE    "Input drawable" 0 
            )
(script-fu-menu-register "script-fu-test-script" "/Filters/Test")

(define (script-fu-test-script image drawable)

    (let* ( )
        
        ; Prep
        (gimp-context-push)
        (gimp-image-undo-group-start image)
        
        ; Actual work here
        
        ; Convert to grayscale
        (gimp-image-convert-grayscale image)
        ;Rotate 90 CCW
        (gimp-image-rotate image ROTATE-270)
        
        ; Finishing Off
        (gimp-image-undo-group-end image)
        (gimp-context-pop)
        (gimp-displays-flush)
    )
)