HowTo: Converting a 2D-Image into OpenSCAD: Difference between revisions
No edit summary |
|||
(2 intermediate revisions by the same user not shown) | |||
Line 82: | Line 82: | ||
And this is, what it looks like: | And this is, what it looks like: | ||
Before:<br>[[Image:2DSCADConversionDemo.png]] | Before:<br>[[Image:2DSCADConversionDemo.png]]<br/>(Turning [[3D-Printing]] up to eleven! :-) ) | ||
After:<br>[[Image:2DSCADConversionDemoResultSCAD.png]] | After:<br>[[Image:2DSCADConversionDemoResultSCAD.png]] | ||
Not bad, eh? | Not bad, eh? | ||
=== The Solution (v6) === | === The Solution (v6) === | ||
Line 206: | Line 206: | ||
Please note: [[3D-Designs Fineprint]]. | |||
---- | ---- |
Latest revision as of 00:13, 18 November 2018
The Challenge
Maybe it's just me - but converting some 2D-image for use in OpenSCAD is insanely hard. But why? Converting an image into an DXF for extruding in OpenSCAD is fairly easy, there a plenty of solutions[1] available. But usually I ended up with an DXF that OpenSCAD wasn't able to parse. Sounds familiar? Yes, you ended up with this:
WARNING: Unsupported DXF Entity 'SEQEND' (40) in "Herforder_Brauerei_logo_v6_sw_cropped.dxf". WARNING: Unsupported DXF Entity 'VERTEX' (1235) in "Herforder_Brauerei_logo_v6_sw_cropped.dxf". WARNING: Unsupported DXF Entity 'POLYLINE' (40) in "Herforder_Brauerei_logo_v6_sw_cropped.dxf".
The Solution (v1)
Then it came to me: The printer has a very limited resolution when printing - so why bother using vector images? Why not just convert a pixel-based image into a bunch of cube()s? KISS!
This is what I came up with after about 20 minutes:
<?php $image="/Users/heiko/Downloads/2DSCADConversionDemo.png"; $outputASCII=false; $outputSCAD=true; $im = imagecreatefrompng($image); // http://php.net/manual/de/function.imagecreatefrompng.php if ($im) { $w = imagesx($im); // image width $h = imagesy($im); // image height for($y = 0; $y < $h; $y++) { for($x = 0; $x < $w; $x++) { $rgb = imagecolorat($im, $x, $y); $r = ($rgb >> 16) & 0xFF; $g = ($rgb >> 8) & 0xFF; $b = $rgb & 0xFF; if ($r+$g+$b>(2*256/3)) { /* "Weisses Pixel" */ if ($outputASCII===true) { echo(" "); } else if ($outputSCAD) { // nix } } else { /* "Schwarzes Pixel" */ if ($outputASCII===true) { echo("#"); } else if ($outputSCAD) { echo("translate([" . $x . ", " . $y . ", 0]) cube([1, 1, 1]);\n"); } } } // x if ($outputASCII===true) { echo("\n"); } } // y echo("Dimensions:\n"); echo("x: " . $x . "\n"); echo("y: " . $y . "\n"); imagedestroy($im); // free resource } else { echo("Fail!"); } ?>
And this is, what it looks like:
Before:
(Turning 3D-Printing up to eleven! :-) )
Not bad, eh?
The Solution (v6)
Then I ran into some "memory exhausted", performance and of course, my favourite "object is not 2-manifold" issues....which lead me to this: (v6)
<?php /* History: 2015-08-29, 20:58, h: Created, published at http://www.wurst-wasser.net/wiki/index.php/HowTo:_Converting_a_2D-Image_into_OpenSCAD 2015-08-31, 20:43, h: Let's see if we can improve this. - not 2-manifold -> make cubes overlap :) --DONE (v3) - Create PCX (RLE)-like compression (adding cubes up if pixels in row have the same colour) (v5) - Refactor (v6) ToDo: */ $image="/Users/heiko/Documents/3D-Modelle/_Meine Designs/Herforder Sandfoermchen/DSCF5594 - Version 3.2 400px c.png"; $outputSCAD=true; // !true (or false if you want aalib-style output (or quick review)) $outputASCII = ! $outputSCAD; // XOR :) - one output method only $sw=0.666; //0.75; //0.5; // 0.25; $im = imagecreatefrompng($image); // http://php.net/manual/de/function.imagecreatefrompng.php if ($im) { $w = imagesx($im); // image width $h = imagesy($im); // image height if ($outputSCAD) { echo("//Created with png2scad. ( http://www.wurst-wasser.net/wiki/index.php/HowTo:_Converting_a_2D-Image_into_OpenSCAD )\n\n"); echo("\$fn=23;\n"); echo("someObject();\n\n"); echo("module someObject()\n"); echo("union()\n{\n"); } for($y = 0; $y < $h; $y++) { for($x1 = 0; $x1 < $w-1; $x1++) { $p1=getPixel($im, $x1, $y); for($x2=$x1+1; $x2 < $w-1; $x2++) { $p2=getPixel($im, $x2, $y); if ($p2!==$p1) break; } if ($outputASCII===true) { for ($i=$x1; $i<=$x2; $i++) if ($p1===true) echo("#"); else echo(" "); } else if ($outputSCAD) { if ($p1===true) { $xLen=$x2-$x1+1+0.01; echo("\ttranslate([" . $x1 . ", " . $y . ", 0]) cube([$xLen, 1.01, 1.01]);\n"); } } $x1=$x2; } /* EOL (not the club) */ if ($outputASCII===true) { echo("\n"); } } // y loop (rows) /*echo("Dimensions:\n"); echo("x: " . $x . "\n"); echo("y: " . $y . "\n");*/ if ($outputSCAD) { echo("}\n"); } imagedestroy($im); // free resource } else { echo("Fail!"); } function getPixel($lIm, $lX, $lY) { global $sw; $rgb = imagecolorat($lIm, $lX, $lY); $r = ($rgb >> 16) & 0xFF; $g = ($rgb >> 8) & 0xFF; $b = $rgb & 0xFF; $grey=($r+$g+$b)/3; if ($grey>(256*$sw)) // < oder > nach Geschmack { return(false); // rather white } else { return(true); // rather black } } ?>
Please note: 3D-Designs Fineprint.
- References and Footnotes:
- ↑ Cloud Services as well as InkScape-Extensions…See: http://www.thingiverse.com/thing:25036/#instructions or https://cloudconvert.com/svg-to-dxf )