Friday, November 29, 2013

awk 'BEGIN { cntr = 0 } /repeating string/ { cntr++ ;OFS=""; print "repeating newString", cntr } !/repeating string/ { print $0 }' thisfile.txt>modified-thisfile.txt

This bash script "one-liner" searches for occurrences of "repeating string" in a file and for each occurrence, replaces the string with "repeating newString" and adds a number (cntr) to that new string, so that the output file (modified-thisfile.txt) has "repeating newString1", "repeating newString2", etc., where the original strings were. I used this to modify material assignments in (3D) obj files (in which the original string in question was "usemtl default").

The problem was that I needed to make the materials assigned to each 3D object unique. These obj files were exported from Cheetah3D, and were to be used with the Element3D plugin in After Effects, which uses separate and unique material assignments to separate objects/polygons.

The OFS part ensures that the number is printed directly after the string, instead of, by default, with a space before it.

Saturday, April 20, 2013

Python Script for getting pixel color on screen in OSX

This post on stackoverflow:, and this blog post: describe a pixel-color-grabbing method using python on OSX. Here is a simplified version, which takes command line arguments and is made to only capture a 1x1 pixel region (this makes it faster for just this functionality) (btw, I shall do my best to get this to format correctly for copying and pasting):

import struct
import operator
import Quartz.CoreGraphics as CG
import sys, getopt

def main():
    args = getopt.getopt(sys.argv[1:], '')
    twoArgs = len(args[1]) == 2
    #print args[1]
    #error correction here to check for [correct] arguments
    if twoArgs:
        argx = args[1][0]
        argy = args[1][1]
            global x
            x = int(argx)
            global y
            y = int(argy)
        except ValueError:
            print "Error! Enter two integers as arguments."
            #print x
            #print y
            sp = ScreenPixel()
            print sp.pixel(0, 0)
        print "Error! Script requires two integers as arguments."

class ScreenPixel(object):
    """Captures the screen using CoreGraphics, and provides access to
    the pixel values.
    ... pass two arguments to script (no comma, no nuthin', a la:
    ./ 112 767
    def capture(self):
        """see original version for capturing full screen
        (and lots of other stuff)
        region = CG.CGRectMake(x, y, 1, 1)
        # Create screenshot as CGImage
        image = CG.CGWindowListCreateImage(
        # Intermediate step, get pixel data as CGDataProvider
        prov = CG.CGImageGetDataProvider(image)
        # Copy data out of CGDataProvider, becomes string of bytes
        self._data = CG.CGDataProviderCopyData(prov)
        # Get width/height of image
        self.width = CG.CGImageGetWidth(image)
        self.height = CG.CGImageGetHeight(image)
    def pixel(self, x, y):
        """Get pixel value at given (x,y) screen coordinates
        Must call capture first.

        # Pixel data is unsigned char (8bit unsigned integer),
        # and there are four (blue,green,red,alpha)
        data_format = "BBBB"
        # Calculate offset, based on
        # [crg]: removed this -- unnecessary step, just using zero
        #offset = 4 * ((self.width*int(round(y))) + int(round(x)))
        # Unpack data from string into Python'y integers
        b, g, r, a = struct.unpack_from(data_format, self._data, offset=0)
        # Return BGRA as RGBA
        return (r, g, b)
        #can (used to) return alpha, too, but in this context, unnecessary
if __name__ == '__main__':