PNG 이미지에서 다이어그램을 렌더링하는 JavaScript 다이어그램 편집기(오픈 소스)


그림 1. dgrm.net은 PNG 이미지에서 다이어그램을 열 수 있습니다.

dgrm.net | GitHub

<< Previous article

dgrm.net - 지식 지도 도구로 변환할 수 있는 다이어그램 편집기입니다.

고유 한 특징:
  • 금욕주의,
  • 휴대폰에서 작동,
  • 오픈 소스.

  • 개발 과정에서 흥미로운 순간이 나타납니다. 오늘은 PNG에서 데이터를 읽는 방법에 대해 이야기하겠습니다. 프로젝트에서 사용할 소스 코드를 첨부합니다.

    PNG 이미지에서 다이어그램을 여는 이유는 무엇입니까?



    개발자가 만든 사용자 인터페이스는 이상하기로 유명합니다. 아마도 이미지를 프로젝트 파일로 사용한다는 아이디어가 바로 그것일 것입니다. 적어도 접근 방식은 독창적입니다.

    모든 편집자는 자신의 프로젝트 파일을 사용합니다. 그러나 이것은 불편합니다.
  • 미리보기 없음,
  • 이미지를 보낼 때 소스도 함께 보내야 합니다.

  • 필요한 경우 편집할 수 있는 다이어그램 그림이 있으면 더 편리합니다.

    그림 1을 보면 스테가노그래피 또는 이미지 인식이 사용되고 있다고 가정할 수 있습니다. 실제로 훨씬 간단하고 핵이 없습니다. PNG 형식은 타임 스탬프, 작성자 이름 또는 기타와 같은 추가 정보 저장을 지원합니다.

    dgrm.net은 다이어그램 데이터가 포함된 JSON을 png 파일에 기록합니다.

    PNG 청크



    다음은 PNG 사양입니다. "Portable Network Graphics (PNG) Specification ".

    가장 밝은 부분:
  • png 파일은 청크라는 블록으로 구성되며,
  • 자신의 청크를 파일에 추가할 수 있습니다.


  • 그림 2. 하나의 PNG 청크 구조

    사용자 지정 데이터의 경우 모든 청크 이름(예: "dgRm")을 생각할 수 있습니다.
  • 이름의 길이는 엄격하게 4개의 라틴 문자입니다.
  • 대소문자가 중요합니다. 사용자 지정 청크의 경우 모든 문자를 소문자로, 세 번째 문자를 대문자로 입력합니다.

  • 따라서 PNG 파일 내에 JSON 문자열을 저장하려면 파일에 자체 청크를 추가해야 합니다.

    브라우저에서 JavaScript로 PNG 청크 읽기/쓰기


    청크 읽기



    청크는 서로 이어지며 필요한 청크는 열거형으로 검색됩니다.

    청크 검색 알고리즘(목록 1):
  • 첫 번째 청크의 이름을 따옴
  • 이름이 검색어와 일치하지 않는 경우
  • 청크의 길이를 가져옵니다(처음 4바이트는 그림 2 참조)
  • 청크의 길이를 알고 커서를 다음 청크의 시작 부분으로 이동합니다
  • .

  • 원하는 청크 또는 'IEND'(파일 끝)를 찾을 때까지 1과 2를 반복합니다.

  • /**
     * @param {ArrayBuffer} pngData
     * @param {number} chunkNameUint32 chunk name as Uint32
     * @returns {DataView | null} chunk data
     */
    function chunkGet(pngData, chunkNameUint32) {
        const dataView = new DataView(pngData, 8); // 8 byte - png signature
    
        let chunkPosition = 0;
        let chunkUint = dataView.getUint32(4);
        let chunkLenght;
        while (chunkUint !== 1229278788) { // last chunk 'IEND'
            chunkLenght = dataView.getUint32(chunkPosition);
            if (chunkUint === chunkNameUint32) {
                return new DataView(pngData, chunkPosition + 16, chunkLenght);
            }
            chunkPosition = chunkPosition + 12 + chunkLenght;
            chunkUint = dataView.getUint32(chunkPosition + 4);
        }
        return null;
    }
    

    목록 1. 청크 조회 기능

    빠른 참조:
    JavaScript에는 바이너리 데이터를 사용하는 흥미로운 방법이 있습니다.

    인용하다:
    ArrayBuffer 개체는 일반적인 고정 길이 원시 이진 데이터 버퍼를 나타내는 데 사용됩니다. …
    ArrayBuffer의 내용을 직접 조작할 수 없습니다.
    developer.mozilla.org

    데이터를 읽으려면 데이터를 DataView 로 래핑할 수 있습니다. DataView를 사용하면 모든 위치의 데이터를 숫자로 읽을 수 있습니다(getInt8(), getUint32() 메서드 등 사용).

    청크 쓰기



    청크를 작성하려면 체인에 새 청크를 삽입해야 합니다. 주어진 이름의 청크가 이미 존재하는 경우 교체해야 합니다.

    GitHub에서 구현 참조 - the chunkSet function .

    소스 코드



    PNG 청크 작업을 위한 기능은 하나의 파일에 있습니다. 이 파일에는 종속성이 없으므로 간단히 프로젝트에 복사할 수 있습니다.

    png-chunk-utils.js

    사용 예:

    // Write a chunk, new blob output
    const newPngBlob = await pngChunkSet(
        // png-image
        pngBlob,
        // chunk name
        'dgRm',
        // chunk value: string as a bytes
        new TextEncoder().encode('...'));
    
    
    // read a chuk
    const dgrmChunkVal = await pngChunkGet(newPngBlob, 'dgRm');
    const str = new TextDecoder().decode(dgrmChunkVal);
    


    목록 2. PNG 청크를 쓰고 읽는 함수 호출

    프로젝트를 지원하는 방법


  • 사용을 시작하고 의견을 알려주세요.
    어떤 식으로든: 댓글, 개인 메시지, GitHub .
    나는 모든 것을 읽고 제안 목록을 보관합니다.
  • 친구에게 알려주세요.
  • GitHub에 별표를 달아주세요 .
  • 좋은 웹페이지 즐겨찾기