> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# QIR SDK (Linux) 博客

对 QIR SDK 示例流水线的技术深度剖析，以及每个新 SDK 版本的发布亮点。

export const POSTS = {
  apriltag: {
    href: "./blogs/apriltag-pipeline-under-the-hood",
    category: "深度剖析",
    title: "深入了解：AprilTag 流水线",
    description: "五个 ROS 2 节点如何将原始摄像头数据转化为毫米级精度的标签位姿。",
    date: "2026 年 7 月"
  },
  "face-detection": {
    href: "./blogs/face-detection-under-the-hood",
    category: "深度剖析",
    title: "深入了解：使用 sample_face_detection 的两阶段人脸检测",
    description: "一个推理节点如何连续运行人脸检测器和关键点模型，完全在设备端完成。",
    date: "2026 年 8 月"
  },
  "release-2-8-0": {
    href: "./blogs/qir-sdk-2-8-0-whats-new",
    category: "发布版本",
    title: "QIR SDK 2.8.0：新功能",
    description: "Qualcomm Linux overlays 登陆 QIR SDK，另外九个示例可在 IQ-8275 EVK 上运行，eSDK 从构建到刷写再到你自己的 recipe 一体化。",
    date: "2026 年 9 月"
  }
};

export const PostCard = ({postKey, hidden, children}) => {
  const post = POSTS[postKey];
  return <a href={post.href} className="mint-group not-prose" style={{
    textDecoration: "none",
    color: "inherit",
    display: hidden ? "none" : "flex",
    flexDirection: "column"
  }}>
      <div style={{
    position: "relative",
    aspectRatio: "16 / 9",
    overflow: "hidden",
    borderRadius: "8px"
  }}>
        {children}
      </div>
      <div style={{
    paddingTop: "0.85rem"
  }}>
        <div style={{
    display: "flex",
    alignItems: "center",
    gap: "0.5rem",
    marginBottom: "0.5rem"
  }}>
          <span style={{
    fontSize: "0.7rem",
    fontWeight: 600,
    padding: "0.15rem 0.55rem",
    borderRadius: "4px",
    background: "rgba(128,128,128,0.12)",
    color: "inherit"
  }}>{post.category}</span>
          <span style={{
    fontSize: "0.8rem",
    color: "rgba(128,128,128,0.9)"
  }}>{post.date}</span>
        </div>
        <div className="group-hover:mint-text-[#31017D] mint-transition-colors mint-duration-200" style={{
    fontSize: "1rem",
    fontWeight: 600,
    lineHeight: 1.4,
    marginBottom: "0.35rem"
  }}>{post.title}</div>
        <p style={{
    fontSize: "0.85rem",
    color: "rgba(128,128,128,0.9)",
    lineHeight: 1.55,
    margin: 0,
    display: "-webkit-box",
    WebkitLineClamp: 2,
    WebkitBoxOrient: "vertical",
    overflow: "hidden"
  }}>
          {post.description}
        </p>
      </div>
    </a>;
};

export const findPostCard = (el, depth = 0) => {
  if (!el || !el.props || depth > 5) return null;
  if (el.props.postKey) return el;
  return React.isValidElement(el.props.children) ? findPostCard(el.props.children, depth + 1) : null;
};

export const matchesPost = (post, query, category) => {
  if (!post) return false;
  if (category && post.category !== category) return false;
  const q = query.trim().toLowerCase();
  if (!q) return true;
  return post.title.toLowerCase().includes(q) || post.description.toLowerCase().includes(q) || post.category.toLowerCase().includes(q);
};

export const cloneWithHidden = (el, hidden) => {
  if (el.props.postKey) return React.cloneElement(el, {
    hidden
  });
  return React.cloneElement(el, {
    children: cloneWithHidden(el.props.children, hidden)
  });
};

export const FilterGrid = ({query, category, children}) => {
  const items = React.Children.toArray(children);
  const posts = items.map(child => {
    const card = findPostCard(child);
    return card ? POSTS[card.props.postKey] : undefined;
  });
  const anyVisible = posts.some(post => matchesPost(post, query, category));
  return <div style={{
    display: "grid",
    gridTemplateColumns: "repeat(2, 1fr)",
    gap: "2rem 1.5rem"
  }}>
      {items.map((child, i) => cloneWithHidden(child, !matchesPost(posts[i], query, category)))}
      {!anyVisible && <p style={{
    fontSize: "0.85rem",
    color: "rgba(128,128,128,0.9)",
    gridColumn: "1 / -1"
  }}>
          未找到文章。
        </p>}
    </div>;
};

export const CATEGORIES = [{
  key: null,
  label: "所有文章"
}, {
  key: "深度剖析",
  label: "深度剖析"
}, {
  key: "发布版本",
  label: "发布版本"
}];

export const BlogSearch = ({children}) => {
  const [query, setQuery] = React.useState("");
  const [category, setCategory] = React.useState(null);
  return <div>
      <div style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    flexWrap: "wrap",
    gap: "0.75rem",
    marginBottom: "1.5rem"
  }}>
        <div style={{
    display: "flex",
    gap: "0.5rem"
  }}>
          {CATEGORIES.map(c => <button key={c.label} onClick={() => setCategory(c.key)} className="not-prose" style={{
    fontSize: "0.85rem",
    fontWeight: 600,
    padding: "0.4rem 0.9rem",
    borderRadius: "999px",
    border: category === c.key ? "1px solid #31017D" : "1px solid rgba(128,128,128,0.3)",
    background: category === c.key ? "#31017D" : "transparent",
    color: category === c.key ? "#fff" : "inherit",
    cursor: "pointer"
  }}>
              {c.label}
            </button>)}
        </div>
        <div style={{
    display: "flex",
    alignItems: "center",
    gap: "0.4rem",
    padding: "0.3rem 0.75rem",
    borderRadius: "999px",
    border: "1px solid rgba(128,128,128,0.3)",
    background: "rgba(128,128,128,0.06)"
  }}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{
    flexShrink: 0,
    opacity: 0.6
  }}>
            <circle cx="11" cy="11" r="8"></circle>
            <path d="m21 21-4.3-4.3"></path>
          </svg>
          <input type="text" value={query} onChange={e => setQuery(e.target.value)} placeholder="搜索文章..." style={{
    border: "none",
    outline: "none",
    background: "transparent",
    color: "inherit",
    fontSize: "0.8rem",
    width: "130px"
  }} />
        </div>
      </div>
      <FilterGrid query={query} category={category}>
        {children}
      </FilterGrid>
    </div>;
};

<BlogSearch>
  <PostCard postKey="apriltag">
    <img noZoom src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/sample-apriltag.gif" alt="深入了解：AprilTag 流水线" className="group-hover:mint-scale-105 mint-transition-transform mint-duration-300 mint-ease-out" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
  </PostCard>

  <PostCard postKey="face-detection">
    <img noZoom src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/sample_face_detection_result.gif" alt="深入了解：使用 sample_face_detection 的两阶段人脸检测" className="group-hover:mint-scale-105 mint-transition-transform mint-duration-300 mint-ease-out" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
  </PostCard>

  <PostCard postKey="release-2-8-0">
    <img noZoom src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/SDKs/QIR-SDK-2.0/media/80-65220-2-qirp-sdk-qsg/qrb-ros-camera_IQ-9075-EVK-main-board.png" alt="QIR SDK 2.8.0：新功能" className="group-hover:mint-scale-105 mint-transition-transform mint-duration-300 mint-ease-out" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
  </PostCard>
</BlogSearch>
