diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,25 @@
+# SIXEL Library for Haskell
+
+SIXEL, short for "six pixels", is a bitmap graphics format supported by terminals and printers from DEC. 
+It can show graphics in a terminal emulator.
+
+[libsixel](https://saitoha.github.io/libsixel/) provides various demos using SIXEL.
+
+This library is developed for displaying images on ghci.
+
+# Usage
+
+This library provides "Show-intances of Sixel-Commands" and "ToSixel type class to change image data into Sixel-Cmmands".
+To render image data on ghci, just run 'toSixel image-data'.
+'putImage' is a wrapper of "readImage 'image-file' >>= putStr.show.toSixel".
+
+See following demo.
+
+![demo](https://raw.githubusercontent.com/junjihashimoto/sixel/master/demo.png)
+
+
+# References
+
+* https://en.wikipedia.org/wiki/Sixel
+* https://saitoha.github.io/libsixel
+
diff --git a/csrc/sixel.c b/csrc/sixel.c
new file mode 100644
--- /dev/null
+++ b/csrc/sixel.c
@@ -0,0 +1,83 @@
+int
+bufsize(int width,int height){
+  return 256+((5+3*3+2+1)*width + 1)*height;
+}
+
+void putnum(unsigned char* buf,int* p, unsigned int r) {
+  int v100 = (r)/100;
+  int v10 = ((r)%100)/10;
+  int v1 = (r)%10;
+  if(v100)
+    buf[(*p)++] = '0' + v100;
+  if(v100 || v10)
+    buf[(*p)++] = '0' + v10;
+  buf[(*p)++] = '0' + v1;
+}
+
+int
+img2sixel(unsigned char* buf, unsigned char* img,int width,int height){
+  int i,j;
+  int p=0;
+  int c;
+  int prev = (100 << 16 ) | (100 << 8 ) | 100;
+  buf[p++] = 033;  // ESC
+  buf[p++] = 'P';
+  buf[p++] = '8';
+  buf[p++] = ';';
+  buf[p++] = '1';
+  buf[p++] = ';';
+  buf[p++] = '0';
+  buf[p++] = 'q';
+  buf[p++] = '"';
+  buf[p++] = '1';
+  buf[p++] = ';';
+  buf[p++] = '1';
+  buf[p++] = ';';
+  putnum(buf,&p,width);
+  buf[p++] = ';';
+  putnum(buf,&p,height);
+  buf[p++] = '#';
+  buf[p++] = '0';
+  buf[p++] = ';';
+  buf[p++] = '2';
+  buf[p++] = ';';
+  putnum(buf,&p,100);
+  buf[p++] = ';';
+  putnum(buf,&p,100);
+  buf[p++] = ';';
+  putnum(buf,&p,100);
+  buf[p++] = '#';
+  buf[p++] = '0';
+  for(j=0;j<height;j++){
+    for(i=0;i<width;i++){
+      int pix = (j*width+i)*3;
+      int r = img[pix]*101/256;
+      int g = img[pix+1]*101/256;
+      int b = img[pix+2]*101/256;
+      int cur = (r << 16) | (g << 8) | b;
+      if (prev != cur){
+	buf[p++] = '#';
+	buf[p++] = '0';
+	buf[p++] = ';';
+	buf[p++] = '2';
+	buf[p++] = ';';
+	putnum(buf,&p,r);
+	buf[p++] = ';';
+	putnum(buf,&p,g);
+	buf[p++] = ';';
+	putnum(buf,&p,b);
+      }
+      buf[p++] = (1 << (j%6))+0x3f;
+      prev = cur;
+    }
+    if(j%6 ==5){
+      buf[p++] = '-'; // LR
+    }else{
+      buf[p++] = '$'; // CR
+    }
+  }
+  buf[p++] = 033;  // END
+  buf[p++] = '\\'; // END
+  return p;
+}
+
diff --git a/sixel.cabal b/sixel.cabal
--- a/sixel.cabal
+++ b/sixel.cabal
@@ -1,6 +1,6 @@
 cabal-version:       >=1.10
 name:                sixel
-version:             0.1.0.0
+version:             0.1.1.0
 synopsis:            Sixel library to show images in a terminal emulator
 description:         Sixel can show graphics on a terminal emulator. This library is developed to showing images on ghci.
 license:             BSD3
@@ -13,6 +13,7 @@
 build-type:          Simple
 extra-source-files:  CHANGELOG.md
                    , demo.png
+                   , README.md
 
 library
   exposed-modules:     Data.Sixel
@@ -20,6 +21,8 @@
   default-language:    Haskell2010
   build-depends:       base >= 4.7 && < 5
                      , JuicyPixels
+                     , vector
+  c-sources:           csrc/sixel.c
 
 executable sixel-exe
   main-is:             Main.hs
diff --git a/src/Data/Sixel.hs b/src/Data/Sixel.hs
--- a/src/Data/Sixel.hs
+++ b/src/Data/Sixel.hs
@@ -6,7 +6,32 @@
 import Codec.Picture
 import Data.Char (chr)
 import Data.Word (Word8)
+import Foreign.C.Types
+import Foreign.ForeignPtr
+import Foreign.Ptr
+import Foreign.C.String
+import           System.IO.Unsafe
+import qualified Data.Vector.Storable          as V
 
+foreign import ccall "bufsize" c_bufsize :: CInt -> CInt -> IO CInt
+foreign import ccall "img2sixel" c_img2sixel :: Ptr () -> Ptr () -> CInt -> CInt -> IO CInt
+
+img2sixel :: Image PixelRGB8 -> String
+img2sixel img = unsafePerformIO $ do
+  let (Image w h vec) = img
+  bsize <- c_bufsize (fromIntegral w) (fromIntegral h)
+  dptr <- mallocForeignPtrBytes (fromIntegral bsize)
+  let (sptr,_) = V.unsafeToForeignPtr0 vec
+  withForeignPtr dptr $ \dst -> do
+    withForeignPtr sptr $ \src -> do
+      len <- c_img2sixel (castPtr dst) (castPtr src) (fromIntegral w) (fromIntegral h)
+      peekCStringLen (castPtr dst, fromIntegral len)
+
+newtype SixelImage = SixelImage { toSixelString :: String } deriving (Eq)
+
+instance Show SixelImage where
+  show (SixelImage img) = img
+
 type ColorNumber = Word8
 
 type PixelPattern = Word8
@@ -50,13 +75,20 @@
   | otherwise = numDigits (n `div` 10) + 1
 
 class ToSixel a where
-  toSixel :: a -> [SixelCmd]
+  toSixel :: a -> SixelImage
 
+instance ToSixel [SixelCmd] where
+  toSixel xs = SixelImage (concat $ map show xs)
+
 instance ToSixel DynamicImage where
   toSixel dimg = toSixel $ convertRGB8 dimg
 
 instance ToSixel (Image PixelRGB8) where
-  toSixel img =
+  toSixel img = SixelImage (img2sixel img)
+--  toSixel img = SixelImage (show (toSixelCmds img))
+
+toSixelCmds :: Image PixelRGB8 -> [SixelCmd]
+toSixelCmds img =
     let width = imageWidth img -1
         height = imageHeight img -1
         header =
@@ -104,7 +136,7 @@
 putImage file = do
   readImage file >>= \case
     Left err -> print err
-    Right img -> putStr $ show $ toSixel img
+    Right img -> putStr $ toSixelString $ toSixel img
 
 demo :: [SixelCmd]
 demo =
