photo/image-to-sketch algorithm

前端 未结 5 1214
生来不讨喜
生来不讨喜 2020-12-12 20:06

Does anyone have an idea, link, library, source code, ... on how to convert photo\'s and images (bitmaps) to sketchy-like pictures? I can\'t find any good sources on how to

5条回答
  •  孤城傲影
    2020-12-12 20:39

    Ok, so i found my own answer using different techniques like Mark told me. I use the following pseudocode:

    *s = Read-File-Into-Image("/path/to/image")
    *g = Convert-To-Gray-Scale(s)
    *i = Invert-Colors(g)
    *b = Apply-Gaussian-Blur(i)
    *result = Color-Dodge-Blend-Merge(b,g)
    

    The first four methods were easily to find on the internet, however on the last one I couldn't find a lot of information, not even source code. So I searched on how PS did it and found the following formula in c++:

    ((uint8)((B == 255) ? B:min(255, ((A << 8 ) / (255 - B)))))
    

    Then i converted it to Java with the following code:

    private int colordodge(int in1, int in2) {
        float image = (float)in2;
        float mask = (float)in1;
        return ((int) ((image == 255) ? image:Math.min(255, (((long)mask << 8 ) / (255 - image)))));
    
    }
    
    /**
     * Blends 2 bitmaps to one and adds the color dodge blend mode to it.
     */
    public Bitmap ColorDodgeBlend(Bitmap source, Bitmap layer) {
        Bitmap base = source.copy(Config.ARGB_8888, true);
        Bitmap blend = layer.copy(Config.ARGB_8888, false);
    
        IntBuffer buffBase = IntBuffer.allocate(base.getWidth() * base.getHeight());
        base.copyPixelsToBuffer(buffBase);
        buffBase.rewind();
    
        IntBuffer buffBlend = IntBuffer.allocate(blend.getWidth() * blend.getHeight());
        blend.copyPixelsToBuffer(buffBlend);
        buffBlend.rewind();
    
        IntBuffer buffOut = IntBuffer.allocate(base.getWidth() * base.getHeight());
        buffOut.rewind();
    
        while (buffOut.position() < buffOut.limit()) {
            int filterInt = buffBlend.get();
            int srcInt = buffBase.get();
    
            int redValueFilter = Color.red(filterInt);
            int greenValueFilter = Color.green(filterInt);
            int blueValueFilter = Color.blue(filterInt);
    
            int redValueSrc = Color.red(srcInt);
            int greenValueSrc = Color.green(srcInt);
            int blueValueSrc = Color.blue(srcInt);
    
            int redValueFinal = colordodge(redValueFilter, redValueSrc);
            int greenValueFinal = colordodge(greenValueFilter, greenValueSrc);
            int blueValueFinal = colordodge(blueValueFilter, blueValueSrc);
    
            int pixel = Color.argb(255, redValueFinal, greenValueFinal, blueValueFinal);
    
            buffOut.put(pixel);
        }
    
        buffOut.rewind();
    
        base.copyPixelsFromBuffer(buffOut);
        blend.recycle();
    
        return base;
    }
    

    If the code could be improved, please post a new answer or comment below. Thanks!

提交回复
热议问题