当前位置: 首页 > news >正文

MATLAB | 如何使用MATLAB一键生成拼豆图纸

最近迷上玩拼豆,就想着能不能写个MATLAB版本的拼豆图纸生成器,目前还是一个很简易版本,只支持生成方形图纸,且不太适合生成超大图(色号显示不清晰),大家可以自行添加功能,或做成App designer 形式。

注意这里如果图像四周如果不是透明的,那么白色像素也会被计数,因此底下显示H1色号会需要非常多,因此代码还有改进的空间,之后可以通过检测白色的连通区域,然后看看是否被其他颜色完全包围来决定是否被统计。。。此外之后可能会尝试对轮廓线条进行自动加粗后再生成图纸。。


1 属性设置

代码就直接点击运行,然后选择想要生成图纸的图片即可,图片如果是非正方形会被自动切割。

代码的最前面几行是:

% 像素画大小; 最大颜色数量
pixN = 50; maxC = 60;
% 是否显示色号, 字体大小
showCName = true; fontSZ = 7;
% 读取色卡
% CData = load('mard188.mat');
CData = load('mard221.mat');
% 色号位置 'bottom'/'right'
palettePos = 'right';

是否显示色号

showCName可以被设置为 true/false,分别有以下效果:

画布尺寸和颜色数量

maxC为最大颜色数量,以下是分别设置为32和8的效果:


pixN是画布尺寸,不建议设置50以上,以下为设置为30的效果:

色卡

色卡这里给了一个188色的mard色卡和一个221色mard色卡,想要用其他牌子的拼豆可以自己制作一个mat文件。

色号位置

可以选择显示在下方还是右侧:


2 其他效果图展示

由于没写轮廓加粗的代码,所以本代码比较适合边缘没那么清晰的图像,此外mard牌子蓝紫色种类比较少,蓝紫色图像绘制效果会稍微差一些:

也可以制作一些游戏角色的拼豆图纸:


3 完整代码

完整代码无配色包文件无法运行,建议从文末链接直接下载包含配色包的压缩包,这里给出代码纯属凑字数。

% 像素画大小; 最大颜色数量
pixN = 50; maxC = 60;
% 是否显示色号, 字体大小
showCName = true; fontSZ = 7;
% 读取色卡
% CData = load('mard188.mat');
CData = load('mard221.mat');
% 色号位置 'bottom'/'right'
palettePos = 'right';% 读取图片并预处理
[filename, filepath] = uigetfile({'*.jpg;*.png;*.bmp;*.tiff', 'Image Files'}, 'Select an Image');
[img, ~, alp] = imread(fullfile(filepath, filename));
[M, N, ~] = size(img); img = double(img)./255; alp = double(alp)./255;
szN = min(M, N) - mod(min(M, N), pixN);
img = img((1:szN) + round((M - szN)/2), (1:szN) + round((N - szN)/2), :);
szB = round([szN, szN]/pixN); 
imgBR = blockproc(img(:,:,1), szB, @(block) mean(block.data(:)));
imgBG = blockproc(img(:,:,2), szB, @(block) mean(block.data(:)));
imgBB = blockproc(img(:,:,3), szB, @(block) mean(block.data(:)));if ~isempty(alp)alp = alp((1:szN) + round((M - szN)/2), (1:szN) + round((N - szN)/2), :);alpB = blockproc(alp, szB, @(block) mean(block.data(:)));imgBR(alpB < .5) = 1; imgBG(alpB < .5) = 1; imgBB(alpB < .5) = 1;
end% 颜色识别 
% 首先识别每个像素最接近哪种颜色,统计各种颜色出现次数
% 之后舍去出现次数少的颜色重新再识别一次
RGB = CData.rgb; CN = size(RGB, 1);
dis = + (repmat(imgBR(:), [1, CN]) - repmat(RGB(:,1).', [pixN^2, 1])).^2 ...+ (repmat(imgBG(:), [1, CN]) - repmat(RGB(:,2).', [pixN^2, 1])).^2 ...+ (repmat(imgBB(:), [1, CN]) - repmat(RGB(:,3).', [pixN^2, 1])).^2;
[~, indC] = min(dis, [], 2);
countC = sum(repmat(indC, [1, CN]) == repmat(1:CN, [pixN^2, 1]), 1);
[countNC, indNC] = sort(countC, 'descend');
indNC = sort(indNC(1:min(find(countNC > 0, 1, 'last'), maxC)));
CName = CData.palette(indNC, 1); RGB = CData.rgb(indNC, :); CN = length(indNC);dis = + (repmat(imgBR(:), [1, CN]) - repmat(RGB(:,1).', [pixN^2, 1])).^2 ...+ (repmat(imgBG(:), [1, CN]) - repmat(RGB(:,2).', [pixN^2, 1])).^2 ...+ (repmat(imgBB(:), [1, CN]) - repmat(RGB(:,3).', [pixN^2, 1])).^2;
[~, indC] = min(dis, [], 2);
countC = sum(repmat(indC, [1, CN]) == repmat(1:CN, [pixN^2, 1]), 1);% 创建图窗
fig = figure('WindowState', 'maximized');
ax = axes('Parent',fig, 'DataAspectRatio',[1,1,1], 'NextPlot','add', ...'Position',[0,0,1,1], 'XColor','none', 'YColor','none');% 绘制像素
for i = 1:length(indNC)if all(RGB(i, :) == 1)elsetind = find(indC == i);[ti, tj] = ind2sub([pixN, pixN], tind);ii = repmat(ti, [1, 4]); jj = repmat(tj, [1, 4]); xx = jj - repmat([0,1,1,0], [size(jj,1), 1]);yy = pixN + 1 - ii - repmat([0,0,1,1], [size(ii,1), 1]);fill(xx.', yy.', RGB(i,:))textC = (mean(RGB(i,:)) < .5).*[1,1,1];if showCNametext(tj - .5, pixN + .5 - ti, CName{i}, 'FontSize',fontSZ, 'Color',textC, ...'FontName','Times New Roman', 'HorizontalAlignment','center')endend
end
fill([-1,pixN,pixN,-1], [-1,-1,0,0], [17,112,189]./255, 'EdgeColor','none')
fill([-1,-1,0,0], [-1,pixN,pixN,-1], [17,112,189]./255, 'EdgeColor','none')
for i = 1:pixNtext([-.5; i - .5], [i - .5; -.5], num2str(i), 'FontSize',fontSZ+1, 'Color','w', ...'FontName','Times New Roman', 'HorizontalAlignment','center')
end% 绘制网格线
xx = [-1:pixN; -1:pixN; nan(1, pixN + 2)]; 
yy = [zeros(1, pixN + 1) - 1; ones(2, pixN + 1).*pixN];
plot([xx(:); yy(:)], [yy(:); xx(:)], 'LineWidth',.5, 'Color',[0,0,0])
xx = [-1, 0:5:pixN; -1, 0:5:pixN; nan(1,length(0:5:pixN)+1)]; 
yy = [zeros(1,length(0:5:pixN)+1) - 1; ones(2,length(0:5:pixN)+1).*pixN];
plot([xx(:); yy(:)], [yy(:); xx(:)], 'LineWidth',1, 'Color',[0,0,0])if strcmp(palettePos, 'bottom')colN = floor((pixN + 1.5)/(3.5));for i = 1:length(indNC)fill([-1,2,2,-1] + mod(i - 1, colN)*3.5, [-1.5,-1.5,-2.5,-2.5] - floor((i-1)/colN)*1.5, RGB(i,:))textC = (mean(RGB(i,:)) < .5).*[1,1,1];text(mod(i - 1, colN)*3.5 + .5, - 2 - floor((i-1)/colN)*1.5, [CName{i}, ' (',num2str(countC(i)),')'], ...'FontSize',fontSZ+1, 'Color',textC, ...'FontName','Times New Roman', 'HorizontalAlignment','center')end
elserowN = floor((pixN + 1.5)/(1.5)); for i = 1:length(indNC)fill([0,3,3,0] + pixN + .5 + floor((i-1)/rowN)*3.5, pixN + [0,0,-1,-1] - mod(i - 1, rowN)*1.5, RGB(i,:))textC = (mean(RGB(i,:)) < .5).*[1,1,1];text(pixN + 2 + floor((i-1)/rowN)*3.5, pixN -.5 - mod(i - 1, rowN)*1.5, [CName{i}, ' (',num2str(countC(i)),')'], ...'FontSize',fontSZ+1, 'Color',textC, ...'FontName','Times New Roman', 'HorizontalAlignment','center')end
endaxis tight

压缩包

  • 链接: https://pan.baidu.com/s/1nGbruD4I5x4BZJx3HgY-LQ?pwd=slan
  • 提取码: slan
http://www.dtcms.com/a/596917.html

相关文章:

  • 如何设计一个高扩展的加密狗集成策略
  • zoho crm 如何设置富文本字段为必填
  • ✨WPF编程进阶【7.1】动画基础
  • 整体设计 全面梳理复盘之31 Transformer 九宫格三层架构 Designer 全部功能定稿(初稿)之3
  • 建设网站需要多久做网站的资源有哪些
  • 手机网站怎么做推广郑州广告公司网站建设
  • 世界各地的软件包:探索 Arch Linux 中的软件包
  • 关于设计图的网站网站新闻百度收录
  • MySQL 迁移总结报告
  • 昆明网站建设公司猎狐科技怎么样南约社区网站建设
  • 跨服务器复制conda环境
  • 联想打印机驱动出现故障怎么办?最新的打印机驱动修复方法
  • 安装部署自己的nginx
  • 技术速递|GitHub Copilot 和 AI Agent 如何拯救传统系统
  • wordpress网站同步插件网络优化的工作流程
  • C语言动态内存管理:从基础到进阶的完整解析
  • Java中的静态代理与动态代理(Proxy.newProxyInstance)
  • 2528. 最大化城市的最小电量
  • 网站建设带服务器新浪舆情通官网
  • 16.udp_socket
  • OpenAI 新推 GPT-5-Codex-Mini:一款针对开发者的轻量级编码助手
  • GPTs智能体案例解析(小红书文案、流程图设计与编辑)
  • 广告宣传网站免费行情软件网站大全
  • 机器学习过拟合和正则化
  • 【SpringBoot】35 核心功能 - 高级特性- Spring Boot 中的Profile 环境配置详解
  • 富利建设集团有限公司网站网络维护怎么做
  • 【VSCode】【Clangd】Win下的基于LLVM/Clangd+Clangd插件+MINGW+CMake的VSCode配置C/C++开发环境的详细教程
  • Java大厂面试真题:从Spring Boot到AI微服务的三轮技术拷问(二)
  • openEuler入门学习教程,从入门到精通,云计算与 Linux 操作系统概述(1)
  • 3.2.STM32-LED闪烁LED流水灯蜂鸣器