2013-04-22 1 views
1

저는 얼마 전 PngLIB로 디스크에서 사진을로드하는 GCC를 사용하여 Linux에서 응용 프로그램을 만들고 있습니다. 이 확장 기능이 제공하는 앤티 앨리어싱 및 알파 채널 속성을 사용하기 위해 표준 xlib에서 Xrender 확장으로 점프했습니다.XRender 디스크/응용 프로그램에서 이미지를 표시합니다.

그러나이 확장은 축소 된 프리미티브 집합을 제공합니다. 예를 들어, 디스크에서로드 된 그림을 표시하려면 pnglib를로드 한 다음 XRenderFillRectangle을 호출하여 너비와 높이 1 픽셀 및 해당 픽셀의 원하는 색을 호출합니다. 그러나 디스크에서로드 된 아이콘과 그림의 수를 늘릴 때 원시적 인 XRenderFillRectangle을 수백만 건으로 쉽게 호출한다는 것을 쉽게 알 수 있습니다. 결론 : 애플리케이션은 이제는 모든 것을 렌더링하는 데 약 20 초 정도 소요되며 렌더링하려는 것의 절반도되지 않습니다.

나는이 접근 방식이 완전히 잘못되었다는 것을 확신하며, 또 다른 방법이 있어야합니다! 또한 카이로 또는 Java2D가 생성하는 방식과 다르다는 것을 확신합니다.

내 질문은 : 어떻게 응용 프로그램에서 생성 된 Xrender 그림의 그림을 준비하고 입력 할 수 있습니까? 예를 들어, 디스크에서로드 된 이미지는?

표준 XPutImage 기능을 Xrender의 그림에 적용 할 수 있습니까? Picture를 생성하기 전에 Pixmap에 데이터를 넣을까요? 지금까지는 내 접근 방식이 효과가 없었습니다.

PS : 카이로 또는 Qt와 같은 더 풍부한 라이브러리를 사용하지 않는 것이 좋습니다. 불행히도이 상황에 관한 게시물을 찾을 때마다 대부분의 사람들의 대답은 다음과 같습니다. 카이로를 사용하십시오. 나는이 X11 시스템으로 가능한 한 낮은 수준으로 머무를 필요가있다. 고맙습니다.

+0

이나요 당신은 [사이트 검색] (http://stackoverflow.com/questions/6609281/how-to-draw-an-image-from-를 사용하려고 file-on-window-with-xlib)? –

+0

내 질문을 읽으려고 했습니까? Xrender 확장을 사용하고 있으므로 XPutImage를 Picture에만 적용 할 수는 없으며 Pixmap에만 적용 할 수 있습니다. – filipehd

+0

일반 xlib을 사용하고 싶지 않은 이유는 무엇입니까? –

답변

2

XRenderCreatePicture는 픽스맵 (또는 임의의 드로어 블)을 매개 변수로 사용합니다. xrender를 사용하여 픽셀을 그릴하기 위해 , 당신이 필요합니다 XPutImage을 사용하여 서버에 픽스맵에게

  • 전송 이미지 데이터를 생성

    • 는 그림 개체가 창문과 관련된 만들고, 픽스맵과 관련된 그림 개체를 만들
    • 는 XRenderComposite

    참조 libXRender의 documentati를 사용하여 구성 node-x11를 사용 here

    예에 :

    var x11 = require('x11'); 
    
    var Exposure = x11.eventMask.Exposure; 
    
    var width = 300; 
    var height = 300; 
    
    var rgb = { 
        data:new Buffer(width*height*4), 
        width: width, 
        height: height 
    }; 
    
    var index; 
    for (var x = 0; x < rgb.width; ++x) 
    { 
        for (var y = 0; y < rgb.height; ++y) 
        { 
        index = (x + y*rgb.width)*4; 
        rgb.data[index] = parseInt(Math.sin(13*x/rgb.width)*255); 
        rgb.data[index+1] = parseInt(Math.cos(15*y/rgb.height)*255); 
        rgb.data[index+2] = parseInt(Math.cos(16*y/rgb.height)*255); 
        } 
    } 
    
    x11.createClient(function(err, display) 
    { 
        var X = display.client; 
        X.require('render', function(Render) { 
        var root = display.screen[0].root; 
        var win, picWin, pic, gc; 
    
        win = X.AllocID(); 
        X.CreateWindow(
         win, root, 
         0, 0, rgb.width, rgb.height, 
         0, 0, 0, 0, 
         { eventMask: Exposure } 
        ); 
        X.MapWindow(win); 
    
        gc = X.AllocID(); 
        X.CreateGC(gc, win); 
    
        var rgbPixmap = X.AllocID(); 
        X.CreatePixmap(rgbPixmap, win, 24, rgb.width, rgb.height); 
        X.PutImage(2, rgbPixmap, gc, rgb.width, rgb.height, 0, 0, 0, 24, rgb.data); 
    
        var rgbPicture = X.AllocID(); 
        Render.CreatePicture(rgbPicture, rgbPixmap, Render.rgb24); 
        var winPicture = X.AllocID(); 
        Render.CreatePicture(winPicture, win, Render.rgb24); 
    
        X.on('event', function(ev) { 
         if (ev.name == 'Expose') 
         Render.Composite(3, rgbPicture, 0, winPicture, 0, 0, 0, 0, 0, 0, rgb.width, rgb.height); 
        }); 
        }); 
    }); 
    
  • +0

    노드 x11에서 예제를 만들 수 있습니까? – exebook

    +0

    예제에는 몇 가지가 있습니다 - https://github.com/sidorares/node-x11/tree/master/examples/png 및 https://github.com/sidorares/node-x11/tree/master/examples/ kbdheatmap 답변을 줄 수있는 짧은 예제를 추가하겠습니다. –