Converting a glyph to a bufferedImage

Hi,
Has anyone every converted a Font Glyph for a given char to a BufferedImage? I am working on some OCR software and am trying to find a programatic way to generate a character training set for patern matching images.
Thanks
Sal

There's a couple ideas in these threads
http://forum.java.sun.com/thread.jsp?forum=31&thread=385662
http://forum.java.sun.com/thread.jsp?forum=31&thread=403943&start=15&range=15&hilite=false&q=

Similar Messages

  • Best way to convert In-Memory bitmap to BufferedImage

    Hello!
    I am working with DirectShow on a Windows system to access a camera. From DirectShow I get called back on every frame with a Pointer to a native Buffer which contains a Bitmap (http://msdn.microsoft.com/en-us/library/windows/desktop/dd376985%28v=vs.85%29.aspx). To be more specific, a 24 Bit Bottom-Up Bitmap.
    The main Problem seems that the Bitmap-Format is encoded Bottom-Up and has a color order blue, green, red instead of red, green, blue. So here is my first approach, but it seems I've stumbled over a known Java-Bug (http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4723021):
    public static void main(String[] args) throws IOException {
        byte[] dataArray = new byte[] { 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1,
                -1 };
        int width = 2;
        int height = 2;
        DataBufferByte dataBuffer = new DataBufferByte(dataArray,
                dataArray.length);
        ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
        ColorModel colorModel = new ComponentColorModel(colorSpace, new int[] {
                8, 8, 8 }, false, false, ColorModel.OPAQUE,
                dataBuffer.getDataType());
        WritableRaster raster = Raster.createInterleavedRaster(dataBuffer,
                width, height, width * 3, 3, new int[] { 2, 1, 0 }, null);
        AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
        tx.translate(0, -height);
        AffineTransformOp transformOp = new AffineTransformOp(tx,
                AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
        BufferedImage image = new BufferedImage(colorModel, transformOp.filter(
                raster, null), false, null);
        ImageIO.write(image, "PNG", new File("test.png"));
    Because this example throws an Exception:
    Exception in thread "main" java.awt.image.ImagingOpException: Unable to transform src image
        at java.awt.image.AffineTransformOp.filter(Unknown Source)
        at at.test.image.ImageTest.main(ImageTest.java:36)
    The Exception is thrown because I changed the band offsets from new int[] { 0, 1, 2 } to { 2, 1, 0 }, meaning the order is blue, green, red. One approach which works is to leave the band offsets in default order (red, green blue), reverse the dataArray and then flip the image horizontally. But is this the fastest way?

    One app that comes to mind would be Graphic Converter (it's not free, but an excellent app for a multitude of things):
    http://www.lemkesoft.com/content/188/graphicconverter.html

  • Converting an image object to  bufferedimage object

    Hi does anyone know how to convert an Image obj to a BufferedImage obj without casting...
    I have generated an image in an applet by rescaling a larger image but i cannot cast it to a BufferedImage as it was declared as an image type...
    thx

    Image img = setupImage(); // or however you set up your Image
    BufferedImage bimg = new BufferedImage(img.getWidth(), img.getHeight, BufferedImage.TYPE_ARGB);
    Graphics g = bimg.getGraphics();
    g.drawImage(img, 0, 0, null);

  • BufferedImage displays as streaky; smooth image not produced

    Hi all,
    I have three classes that I'm working with. One is ImageProcessor, a Class I have to process images. Another is IMAQGUI, a GUI for my IMAQ service, and the third is IMAQIceStormService.
    In IMAQIceStormService, I am using ImageProcessor to create an image from a byte[] that gets sent to me, and I'm using IMAQGUI to display the image on my GUI.
    All this is working fine, except the image does not display properly. I am getting the proper data, as I have compared the camera image to my streaky image, and saw that they are the same. The width, height, depth, and stride should all be correct; 1000x1000 pixels, 8 bits per pixel, and a stride of 0. I recently changed my ImageProcessor code to make some methods static, and I may have broken something.
    Basically, can anyone take a look at my ImageProcessor methods, and possibly give any suggestions as to why the image is not displaying correctly?
    Here is the relevant part of IMAQIceStormService:
         public void imageAcquired(long id, IMAQTypes.ImageDesc imageDesc, byte[] imageData,
              Ice.Current current) {
              IMAQGUI.appendImage(ImageProcessor.createImage(imageData, imageDesc.width, imageDesc.height));
         }IMAQTypes.ImageDesc is simply the image description. It tells me the width, height, depth, and stride of the image. As you can see, I am telling IMAQGUI to appendImage based on what returns from ImageProcessor. First, here is the relevant code from IMAQGUI:
         private static JLabel imageViewer = new JLabel(); // this gets added to the main panel in a different method
         public static void appendImage(BufferedImage image) {
              imageViewer.setIcon(new ImageIcon(image));
              imageViewer.revalidate();
         }This just sets the icon to the new image, and revalidates the JLabel so it displays the new image.
    Finally, here is the most important part. This is the relevant code from ImageProcessor:
        public static BufferedImage toImage(byte[] data, int w, int h) {
            DataBuffer buffer = new DataBufferByte(data, data.length);
            WritableRaster raster = Raster.createInterleavedRaster(buffer, w, h, w,
            1, new int[] {
                0
            } , null);
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
            ColorModel cm = new ComponentColorModel(cs, false, true,
            Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
            return new BufferedImage(cm, raster, false, null);
        public static BufferedImage createImage(byte[] data, int width, int height) {
              BufferedImage im = toImage(data, width, height);
            //image = toImage(data, width, height);
            BufferedImage out = createRGBImage(im);
            return out;
        public static BufferedImage createRGBImage(BufferedImage in) {
            BufferedImage output = new BufferedImage(in.getWidth(), in.getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics2D g = output.createGraphics();
            g.drawRenderedImage(in, null);
            g.dispose();
            return output;
        }I am unsure of why ImageProcessor is creating a streaky image, especially because I know the image dimensions are correct. Is there something I am missing? Does anyone see any mistakes anywhere? Does anyone have any suggestions?
    I know this is a lot of information, so thanks a lot for any help you can provide.

    Hi again,
    I'm still unsure as to what the problem is here. I thought maybe it had something to do with the GUI container, but I saved the BufferedImage to the local filesystem using ImageIO.write(), and it looks the same.
    Although no one has apparently seen any obvious problems, can someone possibly let me know if the methods are correct for what I am trying to do: convert a byte[] to a BufferedImage of RGB format?

  • Assign each half of a glyph (ASCII character) with a different color?

    Okay, this might be an odd one.
    I am using a glyph - Calibri number inside a filled black circle (it doesn't actually matter what glyph) and I want to color the circle part only (leave the background - number, white) with 1/2 red and the other 1/2 green. Are there any tricks in InDesign that would allow this?
    Alternatively, I can convert the glyph to curves in Illustrator and fill the colors... then insert back into InDesign.
    But... just curious about a way to do this inside InDesign??

    BTW,
    I was over at MyFonts.com purchasing some fonts for a job and ran across one of Ray Larabie's (Typodermic.com) fonts that uses OTF features to move characters typed in a given sequence. I mention this because it too is a solution and can have characters/numbers up 6 places. I think it would be relatively easy to GREP the styles needed for each of the parts and this is a means of keeping the numbers in a true circle.
    I don't know which means would be easier. I suppose the paragraph and character styles I created for my example above is the easiest as long as one doesn't need to go beyond the number 20, which is as high as those characters go in Calibri.
    The screen shots are from within the application I was using at the time and show its story editor. First screen shot is the characters used to produce each number, which in turn is the second screen shot when I turn on the formatting in the story editor. Because the story editor swaps out the paper color (white) for black for viewability, the last screen shot is on the page.

  • Image to BufferedImage

    What is the easiest way to convert a Image to a bufferedImage for writing to a file?

    The short answer is to start with a BufferedImage! For instance, use ImageIO.read to read.
    The long aswer, well here's the long answer:
    import java.awt.*;
    import java.awt.image.*;
    import java.net.*;
    import java.text.*;
    import java.util.*;
    import javax.swing.*;
    public class X {
        //preserves image's colormodel. Assumes image is loaded
        public static BufferedImage toBufferedImage(Image image) {
            if (image instanceof BufferedImage)
                return (BufferedImage) image;
            ColorModel cm = getColorModel(image);
            int width = image.getWidth(null);
            int height = image.getHeight(null);
            return copy(createBufferedImage(cm, width, height), image);
        public static BufferedImage toBufferedImage(Image image, int type) {
            if (image instanceof BufferedImage && ((BufferedImage)image).getType() == type)
                return (BufferedImage) image;
            int width = image.getWidth(null);
            int height = image.getHeight(null);
            return copy(new BufferedImage(width, height, type), image);
        //Returns target. Assumes source is loaded
        public static BufferedImage copy(BufferedImage target, Image source) {
            Graphics2D g = target.createGraphics();
            g.drawImage(source, 0, 0, null);
            g.dispose();
            return target;
        public static ColorModel getColorModel(Image image) {
            try {
                PixelGrabber pg = new PixelGrabber(image, 0,0,1,1, false);
                pg.grabPixels();
                return pg.getColorModel();
            } catch (InterruptedException e) {
                throw new RuntimeException("Unexpected interruption", e);
        public static BufferedImage createBufferedImage(ColorModel cm, int w, int h) {
            WritableRaster raster = cm.createCompatibleWritableRaster(w, h);
            boolean isRasterPremultiplied = cm.isAlphaPremultiplied();
            return new BufferedImage(cm, raster, isRasterPremultiplied, null);
        //you may want to use MediaTracker directly
        public static Image load(Image image) {
            ImageIcon ii = new ImageIcon(image);
            if (ii.getImageLoadStatus() != MediaTracker.COMPLETE)
                throw new IllegalArgumentException("unable to load image");
            return image;
        //demo
        public static void main(String[] args) throws MalformedURLException {
            URL url = new URL("http://developers.sun.com/im/logo_java.gif");
            Image image = Toolkit.getDefaultToolkit().createImage(url);
            load(image);
            BufferedImage bi1 = toBufferedImage(image);
            BufferedImage bi2 = toBufferedImage(image, BufferedImage.TYPE_INT_RGB);
            JPanel cp = new JPanel();
            cp.add(createLabel(image, "original"));
            cp.add(createLabel(bi1, "buffered 1"));
            cp.add(createLabel(bi2, "buffered 2"));
            JFrame f = new JFrame("X");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setContentPane(cp);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        //demo
        static JLabel createLabel(Image image, String title) {
            JLabel label = new JLabel(new ImageIcon(image));
            label.setBorder(BorderFactory.createTitledBorder(title));
            return label;
    }I give two versions of toBufferedImage: one takes just an Image and creates a BufferedImage with
    the same ColorModel. That is usually what you want, if you care. The second creates a BufferedImage
    of a given type, like TYPE_BYTE_INDEXED.

  • BufferedImage to Image

    ok im doing this...
    public class Map{
      static ImageIcon image;
      public Map() {
      public void paint(Graphics g){
        Graphics2D g2d = (Graphics2D)g;
        Image im = Toolkit.getDefaultToolkit().getImage("images\\map.gif");
        g2d.drawImage(im,0,0,Config.map);
        int width = 400;
        int height = 400;
        BufferedImage bimage = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.OPAQUE);
        image = new ImageIcon(bimage);
    }Config.map is a JPanel
    When i do this i just get an empty ImageIcon. why is that?

    Yeah ill create the image outside...
    The reason i want to convert an image to a bufferedImage and then back is because i want to draw on it before i convert it back to an image. (which then gets put into the ImageIcon so that i can use it as a JLabel...
    So is this the right way?
    Image im = Toolkit.getDefaultToolkit().getImage("images\\map.gif");
    BufferedImage thumbImage = new BufferedImage(400,400,BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = im.createGraphics();
    g2d.drawImage(im,0,0,400,400,null);
    BufferedImage bimage = g2d.getDeviceConfiguration().createCompatibleImage(400, 400, Transparency.OPAQUE);
    ImageIcon ima = new ImageIcon(bimage);Cause if i do that i get a black image... not sure why...

  • Converting Image to RenderedImage

    Hi All
    I'm relatively new to Java, and my current problem is as follows:
    I'm trying to convert an Image object to a RenderedImage. If anyone has any clue how to do this, I'd be very greatful for your input!
    Alternatively, does anyone know how to output an Image to a File?
    Thanks!
    Dr Nick

    BufferedImage implements the RenderedImage interface. So what you may want to do is convert your Image to a BufferedImage. They will function the same.
    Use ImageIO in the API:
    static BufferedImage read(ImageInputStream stream)
    Returns a BufferedImage as the result of decoding a supplied ImageInputStream with an ImageReader chosen automatically from among those currently registered. Here's something you may try.
    BufferedImage image = ImageIO.read(file.toURL());You could also do a cast.
    Image i = Toolkit.getDefaultToolkit().getImage("MyImage.jpg");
    BufferedImage bi = new BufferedImage (i.getWidth(this), i.getHeight(this), BufferedImage.TYPE_INT_ARGB);
    bi = (BufferedImage)i;(Note you may skip BufferedImage instantiation on the second line and set the new variable to null)
    You may also get a Graphics object on BufferedImage object and draw the Image object on it:
    g2d.drawImage(i, 0, 0, bi.getWidth(this), bi.getHeight(this), this);
    .Let us know if this works for you.
    Regards,
    Devyn

  • Converting Image to Byte Array and then to String

    Hi All...
    Can anyone please help me. I have got a problem while converting a Byte array of BufferedImage to String.
    This is my code, First i convert a BufferedImage to a byte array using ImageIO.wirte
    public String dirName="C:\\image";
    ByteArrayOutputStream baos=new ByteArrayOutputStream(1000);
    BufferedImage img=ImageIO.read(new File(dirName,"red.jpg"));
    ImageIO.write(img, "jpg", baos);
    baos.flush();
    byte[] resultimage=baos.toByteArray();
    baos.close();
    Then i tried to convert this byte array to a string
    String str=new String(resultimage);
    byte[] b=str.getBytes();
    This much worked fine. But when i reversed this process to re-create the image from that string. i found the image distroted.
    BufferedImage imag=ImageIO.read(new ByteArrayInputStream(b));
    ImageIO.write(imag, "jpg", new File(dirName,"snap.jpg"));
    I got this snap.jpg as distroted.
    Please help me i have to convert the image to a string and again i have to re-create the image from that string.

    To conver the bytearray to string use base64.encoding
    String base64String= Base64.encode(baos.toByteArray());
    To convert back use Base64.decode;
    byte[] bytearray = Base64.decode(base64String);
    BufferedImage imag=ImageIO.read(bytearray);

  • BufferedImage turns up black

    I'm a newbie to graphics programming, so it baffles me that the space on my applet, where a BufferedImage image would normally appear, is just a black screen. I have a red rectangle that draws shortly after that and you can move it around, so I know it's not a problem with finding the images in the directory. The red rectangle responds to key presses.
    //Fields
    private BufferedImage image;
    private boolean imagecreated = false;
    public void drawMap(Graphics g)
            if(!imagecreated)
                Graphics2D g2d = image.createGraphics();
                Image tile;
                //a is a substitute for x
                for(int a=0;a<viewportsize;a++)
                    //b is a substitute for y
                    for(int b=0;b<viewportsize;b++)
                        tile = tilebuffer.fetchImage(tiles[a]);
    g2d.drawImage(tile,a*tile.getWidth(applet), b*tile.getHeight(applet), applet);
    imagecreated = true;
    g2d.dispose();
    g.drawImage(image,0,0,applet);
    }I believe the background of my applet is black because of the doublebuffering method I picked up from another website, which leads me to believe, am I drawing on the BufferedImage incorrectly? If someone could help, it would be greatly appreciated.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

    Hello again! Morgalr I thought it'd be implied that I instantiated. I did do that in the constructor.
    I have found the solution! Instead of using an Image I turn it into a BufferedImage, and it magically worked. Odd.
    Here is the code I used:for(int b=0;b<viewportsize;b++)
           tile = tilebuffer.fetchImage(tiles[a]);
    g2d.drawImage(ImageLoader.toBufferedImage(tile),a*tile.getWidth(applet), b*tile.getHeight(applet), applet);
    }And here is the correct code (I hope it doesn't cause problems later!):for(int b=0;b<viewportsize;b++)
    tile = tilebuffer.fetchImage(tiles[a][b]);
    ImageLoader.toBufferedImage(tile); //converts an Image to a BufferedImage
    g2d.drawImage(ImageLoader.toBufferedImage(tile),a*tile.getWidth(applet), b*tile.getHeight(applet), applet);
    }Thanks to those who helped. :)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Animated gif frame count & fps

    How do I find out details of an animated gif? I need to know the number of images in a strip, and also the frame rate. I would like to convert the strip to a BufferedImage for animation.

    See http://www.fmsware.com/stuff/gif.html for a free decoder.
    It will give you a frame count, and return each frame as a BufferedImage. It will also tell you the duration of each frame (animated GIF's don't have a fixed frame rate).
    -- Kevin

  • Getting a pixel in an image

    How can i get the color of a pixel in an Image object, or an array of bytes or integers of the image.

    use getRGB(int x, int y) method of BufferedImage.
    first convert your image object to bufferedImage object. then use above method.
    if any problems contact
    [email protected] or [email protected]
    best of luck!

  • Large Bitmaps create out of memory  exception

    Hello,
    I try to generate a "BufferedImage" from a Windows Bitmap file ( xxxx.BMP ) .
    I can read and generate relatively images from relatively small files (e.g. 852x626 pixels works fine),
    but if it comes to larger images, I get an out of memory exception.
    Has anybody an idea how to convince Java to read also large BMP image files.
    If I create an awt "Image" even large images (eg 1200x5000 pixels are generated).
    But unfortunately I have found no way to convert an "Image" to a "BufferedImage" and
    only "BufferedImage" offers all the processing methods needed.
    This is the code snippet I wrote:
    ------------ start of code snippet -----------------------------------------------------
    try {
    DataBufferInt dbBMPInt = new DataBufferInt(nwidth*nheight);
    System.out.println("DataBufferInt = "+dbBMPInt);
    int [] bitMasks = new int[3];
    bitMasks[0] = (int)0xff<<16;
    bitMasks[1] = (int)0xff<<8;
    bitMasks[2] = (int)0xff;
    SinglePixelPackedSampleModel spSM = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT,nwidth,nheight,bitMasks);
    System.out.println("SinglePixelPackedSampleModel = "+spSM);
    WritableRaster bmpRaster = WritableRaster.createWritableRaster((SampleModel) spSM, (DataBuffer) dbBMPInt, new Point(0,0));
    System.out.println("WritableRaster = "+bmpRaster);
    bmpImage = new BufferedImage(nwidth,nheight,BufferedImage.TYPE_3BYTE_BGR);
    System.out.println("BufferedImage = "+bmpImage);
    bmpImage.setData(bmpRaster);
    catch (Exception exCrBm)
    { /* 001 start catch */
    exCrBm.printStackTrace ();
    } /* 001 end catch */
    ----------------------------------------------- end of code snippet --------------------
    and this is the generated output.
    File type is :BM
    Size of file is :1600110
    Size of bitmapinfoheader is :40
    Width is :852
    Height is :626
    Planes is :1
    BitCount is :24
    Compression is :0
    SizeImage is :1600056
    DataBufferInt = java.awt.image.DataBufferInt@1774b9b
    SinglePixelPackedSampleModel = java.awt.image.SinglePixelPackedSampleModel@8080b54
    WritableRaster = IntegerInterleavedRaster: width = 852 height = 626 #Bands = 3 xOff = 0 yOff = 0 dataOffset[0] 0
    BufferedImage = BufferedImage@b9e45a: type = 5 ColorModel: #pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_ColorSpace@3ef810 transparency = 1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 852 height = 626 #numDataElements 3 dataOff[0] = 2
    Any help appreciated
    Regards
    Wolfgang

    Increase your maximum heap memory size.
    Se -Xmx parameter of java.exe
    Have a nice programming day,
    Jos�.

  • Problem with  M-JPEG by using JMF and JPEGCodec .

    Hi, there,
    I want to implement a M-JPEG using JMF and JPEGCodec, is that possible?(I already been trapped)
    My problem is I have a video clip which is a AVI file, the video format is following:
    Video format: RGB, 160x120, FrameRate=14.9, Length=57600, 24-bit, Masks=3:2:1, P
    ixelStride=3, LineStride=480, Flipped.
    I already convered a frame to an Image object(video format with JPEG and CVID doesn't work) ,
    I can also convert this Image back as a Buffer, It works fine with me .But to use JPEGCodec( provided by com.sun.image.codec.jpeg ) I need to convert an Image to a BufferedImage, I use the following defination:
    BufferedImage   bImage = new BufferedImage(frameImage.getWidth(null), frameImage.getHeigh(null),BufferedImage.TYPE_INT_RGB); It seems work, But when I use JPEGImageEncoder to encoder this bImage and save as a jpg file,
    everything is black .
    I also need to cast BufferedImage to an Image: frameImage = (Image) bImage; then I convert frameImage back to Buffer.My video clip still running , but every frame now became black .
    can someone help me? thanks in advance.

    I solved this problem . But I met a new problem.
    I converted the above video clip into a JPEG and I want to create a DataSink for it. the messege is:
    Video format: JPEG, 160x120, FrameRate=12.0, Length=3574
    - set content descriptor to: AVI
    - set track format to: JPEG
    Cannot transcode any track to: JPEG
    Cannot create the DataSink: javax.media.NoDataSinkException: Cannot find a DataS
    ink for: com.sun.media.multiplexer.RawBufferMux$RawBufferDataSource@2b7eea
    Transcoding failedHope some Java Experts can help me.
    Regards.

  • JPEG to Clipboard

    One of my tasks is to handle a "screenshot" like function in our app. We want to be able to copy our image and paste it into another app, like Photoshop, so the clipboard needs to be a system clipboard, and the format needs to be universal. I think we should be going for JPEGs, as they allow lots of colors and the code can be cross platform.
    I am using a PixelGrabber to grab the pixels, handing those pixels off to a Toolbox.createImage method (which creates a Java Image), converting the Image to a BufferedImage, then using JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(aFileOutputStream) to encode the bufferedimage as a JPEG.
    So far, this works okay. I can write the JPEG to t file and view it with another app. My problem comes with placing the image on the clipboard. I have tried to create a class for this:
    class TransferableJPEG extends ByteArrayOutputStream implements Transferable{
         // converts Image into TransferableJPEG
    Though I don't get any errors, I don't seem to be getting anything into the clipboard.
    TransferableJPEG image = cif.createTransferableJPEG(pixels, width, height);
    try {
         clipboard.setContents(image,this);
    Anyone tried something like this? Am I wrong about the clipboard's requirement that all data to copy/paste must contained in a object that extends Transferable? If that is the case, how can I paste just the data portion of my JPEG, without any of the Object's wrappings?
    ps. I am using a Maintosh for this, if that matters.

    See the DragPictureDemo2 example in the section Adding Cut/Copy/Paste Support of the
    How to Use Drag and Drop and Data Transfer online tutorial.

Maybe you are looking for