Color values to skm code

cheers, it’s not really worth a wrapper in that case…

the PHP alternative for a ‘plugin’ would be to use Ruby for the ‘xml’, ‘Chuncky_PNG.gem’ for the Thumbnail, and ‘Rubyzip’ to create the skm…

a quick test returned png’s are a third of the size?


I checked the link you gave me … the documentation is slanted toward webservers which I find misleading and requires me to first download the Microsoft Web Platform Installer … however, in only a few minutes, I was able to download one of the binaries from “PHP For Windows: Binaries and sources Releases” and edit the system PATH and PATHEXT variables to get the CLI to work. Not terribly difficult to do, but it seems like a lot of work to add an import function to SketchUp. Normally, I advise against potentially invasive installs on a workstation to accomplish a single task (as a work-around, in this case). However, that said, the files are only about 42MB in size, require no registry edits, and now gives me a way to run PHP on my computer if I should ever need to do so. It’s a lot less invasive than installing Perl on my computer :wink:

1 Like

I cobbled a ruby version together …

you need ruby 2 version of SU use Gem.install ‘chunky_png’ and ‘rubyzip’,in Ruby Console, if you don’t have them…

require 'fileutils'
require 'chunky_png'
require 'zip' unless defined? Zip::File # workaround for SCF install...

  file = UI.openpanel('Select CSV File', '~', 'CSV Files|*.csv;||')
  base = File.basename(file, '.csv')
  mats = Sketchup.find_support_file('Materials')
  main = File.join(mats, base)
  Dir.mkdir(main) unless Dir.exist?(main)
  input =, 'r')
  while (line = input.gets)
    values = line.split(',')
    name = values[1].rstrip
    r = values[2].to_i
    b = values[3].to_i
    g = values[4].to_i
    next if name == 'Name'
    png =, 64, ChunkyPNG::Color::TRANSPARENT)
    for y in 1...64
      for x in 1...64
        png[x, y] = ChunkyPNG::Color.rgba(r, b, g, 255)
    col = File.join(main, name)
    Dir.mkdir(col) unless Dir.exist?(col)
    thumb = File.join(col, 'doc_thumbnail.png'), interlace: true)

    document = <<XML
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<materialDocument xmlns="" xmlns:mat="" xmlns:r="" xmlns:xsi="" xsi:schemaLocation="">

  <mat:material colorBlue="#{b}" colorGreen="#{g}" colorRed="#{r}" colorizeType="0" hasTexture="0" name="[#{name}]" trans="0" type="0" useTrans="0"/>



    col_document = File.join(col, 'document.xml'), 'w') { |f| f << document }

    refs = <<XML
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<references xmlns="" xmlns:r="" xmlns:xsi="" xsi:schemaLocation=""/>


    ref_document = File.join(col, 'references.xml'), 'w') { |f| f << refs }

    timestamp ='%F%Z%T.%LZ')

    documentProperties = <<XML
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<documentProperties xmlns="" xmlns:dp="" xmlns:xsi="" xsi:schemaLocation="">










  <dp:generator dp:name="Material" dp:version="1"/>



    doc_Properties = File.join(col, 'documentProperties.xml'), 'w') { |f| f << documentProperties }

    input_filenames = [ 'document.xml', 'references.xml', 'documentProperties.xml', 'doc_thumbnail.png']
    zipfile_name = col + '.skm', Zip::File::CREATE) do |zipfile|
      input_filenames.each do |filename|
        zipfile.add(filename, col + '/' + filename)



I like this approach much better than having to install PHP to create the PNG files and zip them. Once again, @john_drivenupthewall, you’ve gone way over the top :slight_smile:

When I get back from vacation next year, I’ll add your code to my computer. My little netbook for-the-road only has SketchUp 8 so I can’t do it on here (but now it has PHP when I need it).

happy new year @ all.

@ lori

i have a script that change me RGB to skm

format is a csv file to import

color name,R,G,B

if you need this… i have this from Sd mitch in the scetchucation forum.
so i write this in excel and export this and than import.

4000 color is a little bit heavy… the script would work however a little bit waitig for result.

@john_drivenupthewall - it worked great John! the only issue was Sketchup got very cranky and unstable loading all 4000+ colors. I ended up separating the materials libraries into smaller chunks (1500 per library) and that made everyone happy. Thanks again for your help - it’s safe to say I wouldn’t have made the deadline without it :smile:

that’s good news…
did you use the ruby or php version?

was that when using the ruby script or on restarting SU with a 4000 material folder?


I used the php version. The unstable part was after restarting with loading 4000 materials folder. I used SU 2015 since 2016 had warnings about backwards compatibility so I’m not sure if it would’ve worked better with 2016.

The Sketchup plugin what i use work with 2016 and you can safe in all other formats like 2015 and older

@john_drivenupthewall Hi! You were so kind as to create the awesome PHP script in this thread for me back at the end of 2015. I have to perform the same task again and have completely forgotten how to use the PHP script. Would it be possible for you to refresh my memory? ~ lori

Since SU2017 this can all be done by the SketchUp API without the gems.

1 Like

hi Dan, lori has upgraded to SU v16…

else material.save_as(filename) would do the trick…


okay, well Sketchup::Material#write_thumbnail has been around since SketchUp 8.0 M1, so probably no need for Chunky at least. Still will need RubyZip.

1 Like

@lori, see if you can go to SU v17 at least…


@john_drivenupthewall I just updated to SU 2020 pro. Does that help?



this works in v19 and v20 on my mac…

    version = Sketchup.version.to_i
    osx     = Sketchup.platform == :platform_osx
    # select a colour list
    file = UI.openpanel(
      'Select CSV File',
      osx ? '~' : ENV['HOME'],
      osx ? '*.csv' : 'CSV Files|*.csv||'

    if version >= 17
      # extract folder name
      dir = File.basename(file, '.csv')

      # create array of name and hex value
      require 'csv.rb'
      csv_data = CSV.foreach(file, headers: true).map do |row|
        h = row.to_h
        n = h['Name'].split(' ').map(&:capitalize).join(' ').rstrip
        c = [ h['R'].to_i, h['G'].to_i, h['B'].to_i ]

      #create new material
      # Get a handle to all the materials in the current model.
      model = Sketchup.active_model
      mats = model.materials
      path = Sketchup.find_support_file('Materials')
      main = File.join(path, dir)
      Dir.mkdir(main) unless Dir.exist?(main)

      # process data
      @mat = mats.add('placeholder')
      csv_data.each do |name,colour|
        filename = File.join(main, name + '.skm') = name
        @mat.color =

the test css I used is (439 Bytes)

to run either copy paste the code into Ruby Console or use

EDIT removed file for now…

load ' <drag the downloaded file here, replacing this text> '

and hit Enter…


1 Like

This is awesome! One quick thing - I’m on a PC, do I need to add something to the top part where osx is?

No Lori that’s just a local reference used for conditional expressions.

Just note that …

file = UI.openpanel('Select CSV File', '~', 'CSV Files|*.csv;||')

… on Windows defaults to the current working directory which is probably your user Documents folder.

@John… it’s safer & cross platform to use ENV["HOME"] instead of "~" (SketchUp adds the HOME variable to the environment when it loads on Windows.)

Oh … ADD: … another thing for windows filetype filters, only use a semicolon when there are multiple types listed. Your example displays as …


… so the semicolon after “*.csv” is frivolous and looks a bit weird as if the choice has a semicolon as part of the file extension.

1 Like

Actually john didn’t even use the osx reference, but could have like …

    file = UI.openpanel(
      'Select CSV File',
      osx ? '~' : ENV['HOME'],
      osx ? '*.csv' : 'CSV Files|*.csv||'

… instead of the 5th statement.

1 Like

I’ll update the code as I normally do similar to Dan’s suggestion for UI.openpanel

the reference was there for some mac SU version testing…

totally useless on a windows PC…

      if osx & (version != 20)
          osascript -e 'tell application "System Events" to key code 124 using control down'
          sleep 1
          osascript -e 'tell application "System Events" to key code 123 using control down'