import React, { Fragment, useState } from "react"; import tinycolor from "tinycolor2"; import _ from "lodash"; import { JBX, MainHeader, Text, Space, A, Container, Dropzone, Ul, Li, Tabs, Tab, Inline, } from "jbx"; import Styled from "styled-components"; import { imageToRGBMatrix, imageToRawData } from "canvas-image-utils"; const Textarea = Styled.textarea({ fontFamily: "monaco, monospace", border: "none", width: "100%", height: 256, fontSize: 13, lineHeight: 1.309, padding: "16px 18px", background: "#ecf0f1", color: "#34495e", ":focus": { outline: "none", }, }); function compressColor(rgb) { const hex = tinycolor(rgb).toHexString(); switch ( hex // based on CSS3 supported color names http://www.w3.org/TR/css3-color/ ) { case "#c0c0c0": return "silver"; case "#808080": return "gray"; case "#800000": return "maroon"; case "#ff0000": return "red"; case "#800080": return "purple"; case "#008000": return "green"; case "#808000": return "olive"; case "#000080": return "navy"; case "#008080": return "teal"; } return hex[1] === hex[2] && hex[3] === hex[4] && hex[5] === hex[6] ? "#" + hex[1] + hex[3] + hex[5] : hex; } function App() { const [outputType, outputTypeSet] = useState("SHADOW"); const [originalSize, originalSizeSet] = useState(0); const [base64Data, base64DataSet] = useState(""); const [rgbMatrix, rgbMatrixSet] = useState(null); const [loadingImage, loadingImageSet] = useState(false); function onFileSelected(event) { event.stopPropagation(); event.preventDefault(); const dt = event.dataTransfer; const files = dt ? dt.files : event.target.files; const file = files[0]; originalSizeSet(file.size); const fr = new window.FileReader(); loadingImageSet(true); fr.onload = async (data) => { const base64src = data.currentTarget.result; const dataMatrix = await imageToRGBMatrix(base64src, { size: 200 }); const canvasRawData = await imageToRawData(base64src, { size: 1080, crop: false, }); base64DataSet(canvasRawData.ctx.canvas.toDataURL("image/jpeg", 0.66)); rgbMatrixSet(dataMatrix); loadingImageSet(false); }; fr.readAsDataURL(file); } function onDragOver(event) { event.stopPropagation(); event.preventDefault(); } let scale = 1; const masterShadow = _.map(rgbMatrix, (row, rowIndexSrc) => { return _.map(row, (col, colIndexSrc) => { const i = colIndexSrc * scale; const j = rowIndexSrc * scale; const color = compressColor(`rgb(${col.r},${col.g},${col.b})`); const scaleCompensation = scale !== 1 ? ` 0 ${scale / 2}px` : ``; return `${color} ${j ? j + "px" : 0} ${ i ? i + "px" : 0 }${scaleCompensation}`; }).join(","); }).join(","); const handleFocus = (event) => { event.preventDefault(); event.stopPropagation(); event.target.select(); }; return ( img2css This is a tool that can convert any image into a pure css image. {loadingImage ? ( Processing... ) : (
Drop an image here or click to select
)}
I also made a per-pixel animation experiment using the box-shadow idea, see morphin. {rgbMatrix && ( { outputTypeSet("SHADOW"); }}> {"Pure CSS"} { outputTypeSet("BASE64"); }}> {"Base64"} {outputType === "BASE64" && ( The result (base64).{" "} { "This is your image tag a base64 output. The entire image file is embedded inside the `` tag using base64, so no need external hosting is needed." }