【代码片段】取最接近的Web-Safe Color

本文介绍了一种用于CSS编辑器的颜色匹配算法,该算法能够从索引颜色中选取与目标颜色最接近的颜色。通过计算RGB值之间的距离来确定最佳匹配,并提供了用于生成Web安全颜色调色板的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者: RayLinn

最近的项目里需要从索引颜色里取最接近的颜色,用下面的代码实现之:

[code]
public static Color ScanNearestColor(Color color)
{
int leastDistance = int.MaxValue;
int red = color.R;
int green = color.G;
int blue = color.B;
byte colorIndex = 255;
Color[] _colors = GetColorPalette();
for (int index = 0; index < _colors.Length; index++)
{
// Lookup the color from the palette
Color paletteColor = _colors[index];

// Compute the distance from our source color to the palette color
int redDistance = paletteColor.R - red;
int greenDistance = paletteColor.G - green;
int blueDistance = paletteColor.B - blue;

int distance = (redDistance * redDistance) +
(greenDistance * greenDistance) +
(blueDistance * blueDistance);

// If the color is closer than any other found so far, use it
if (distance < leastDistance)
{
colorIndex = (byte)index;
leastDistance = distance;

// And if it's an exact match, exit the loop
if (0 == distance)
break;
}
}
return _colors[colorIndex];
}
[/code]

代码里的GetColorPalette返回索引颜色表,比如下面是生成Web安全色的颜色表:
[code]
private static Color[] GetWebSafeColorPalette()
{
Color[] aSafeCols = new Color[216];
int rValue, gValue, bValue;
int iPointer = 0;
for (rValue = 0; rValue <= 255; rValue += 51)
{
for (gValue = 0; gValue <= 255; gValue += 51)
{
for (bValue = 0; bValue <= 255; bValue += 51)
{
aSafeCols[iPointer] = Color.FromRgb((byte)rValue,(byte)gValue,(byte)bValue);
iPointer += 1;
}
}
}
[/code]

基本最后完成的是个基于Visual studio的CSS编辑器,配上上个项目里为CSS的颜色定义添加相应颜色的下划线,这样的CSS编辑器相当不错了,如果要完美一点,还可以加上图片预览的功能。

[img]http://dl.iteye.com/upload/attachment/281259/e0ee4dd2-60b5-306f-9d69-b00352f0dbd5.png[/img]

参考:
http://msdn.microsoft.com/en-us/library/aa479306.aspx
<template> <view class="container"> <web-view :src="webviewPath" id="targetWebview" @message="handleWebviewMessage" ></web-view> <cover-view class="bottom-action-area"> <cover-view class="capture-btn" @click="generatePDF"> <cover-view class="btn-text">立即证</cover-view > </cover-view > </cover-view > <!-- PDF预览组件 --> <cover-view v-if="showPreview" class="pdf-preview"> <cover-view class="preview-header"> <cover-view class="title-container"> <cover-view class="preview-title">证据预览</cover-view > </cover-view > </cover-view > <web-view v-if="pdfPreviewUrl" :src="pdfPreviewUrl" class="preview-iframe" ></web-view> <cover-view class="action-buttons"> <cover-view class="action-btn cancel-btn" @click="closePreview">放弃</cover-view > <cover-view class="action-btn confirm-btn" @click="savePDF">保存证据</cover-view > </cover-view > </cover-view > </view> </template> <script setup lang="ts"> import { ref, onMounted } from 'vue'; import { onLoad, onReady } from '@dcloudio/uni-app'; import html2canvas from 'html2canvas'; // 状态管理 const webviewPath = ref(''); const showPreview = ref(false); const pdfPreviewUrl = ref(''); const pdfFilePath = ref(''); const currentWebview = ref<any>(null); const platform = ref(''); const ws = ref<any>(null); // 初始化 onLoad((options: any) => { if (options.url) { webviewPath.value = decodeURIComponent(options.url); } // 获平台信息 const systemInfo = uni.getSystemInfoSync(); platform.value = systemInfo.platform || ''; }); // 准备阶段获 WebView 实例 onReady(() => { // #ifdef APP-PLUS const pages = getCurrentPages(); const page = pages[pages.length - 1]; const webview = page.$getAppWebview(); setTimeout(() => { if (webview.children().length > 0) { const wv = webview.children()[0]; ws.value = wv; console.log(ws.value) } }, 1000); // #endif }); // 生成PDF const generatePDF = () => { uni.showLoading({ title: '生成证据中...', mask: true }); // #ifdef APP-PLUS // const wv = this.$scope.$getAppWebview(); setTimeout(() => { if (!ws.value) { uni.showToast({ title: '网页未加载完成', icon: 'none' }); return; } const timestamp = new Date().getTime(); const pdfPath = `_doc/evidence_${timestamp}.pdf`; // 使用 plus.draw 生成PDF ws.value.draw(ws.value, { format: 'pdf', filename: pdfPath, background: '#FFFFFF', success: (res:any) => { pdfFilePath.value = res.filePath; preparePDFPreview(res.filePath); uni.hideLoading(); }, fail: (err:any) => { console.error('PDF生成失败:', err); uni.hideLoading(); uni.showToast({ title: `生成失败: ${err.message}`, icon: 'none' }); } }); }, 800) // #endif // #ifdef H5 // H5环境使用html2canvas + jsPDF generatePDFForH5(); // #endif }; // 准备PDF预览 const preparePDFPreview = (filePath: string) => { // #ifdef APP-PLUS plus.io.resolveLocalFileSystemURL( filePath, (entry) => { const localUrl = entry.toLocalURL(); // 使用PDF.js预览 pdfPreviewUrl.value = `/static/pdfjs/web/viewer.html?file=${encodeURIComponent(localUrl)}`; showPreview.value = true; }, (err) => { console.error('文件访问失败:', err); uni.showToast({ title: '文件访问失败', icon: 'none' }); } ); // #endif }; // 保存PDF到相册 const savePDF = () => { // #ifdef APP-PLUS if (!pdfFilePath.value) return; // plus.gallery.save( // pdfFilePath.value, // { filename: `evidence_${Date.now()}.pdf` }, // () => { // uni.showToast({ title: '证据保存成功' }); // closePreview(); // }, // (err) => { // uni.showToast({ title: `保存失败: ${err.message}`, icon: 'none' }); // } // ); // #endif // #ifdef H5 // H5环境下载PDF const link = document.createElement('a'); link.href = pdfFilePath.value; link.download = `evidence_${Date.now()}.pdf`; link.click(); closePreview(); // #endif }; // 关闭预览 const closePreview = () => { showPreview.value = false; pdfPreviewUrl.value = ''; }; // H5环境PDF生成(使用html2canvas + jsPDF) const generatePDFForH5 = () => { // #ifdef H5 // const iframe = document.getElementById('targetWebview') as HTMLIFrameElement; // if (!iframe || !iframe.contentWindow) return; // const iframeDoc = iframe.contentWindow.document; // html2canvas(iframeDoc.body, { // useCORS: true, // scale: 2 // }).then(canvas => { // const imgData = canvas.toDataURL('image/jpeg', 0.95); // const pdf = new jsPDF('p', 'mm', 'a4'); // const imgWidth = pdf.internal.pageSize.getWidth(); // const imgHeight = (canvas.height * imgWidth) / canvas.width; // pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight); // const pdfBlob = pdf.output('blob'); // pdfFilePath.value = URL.createObjectURL(pdfBlob); // // H5环境预览 // pdfPreviewUrl.value = pdfFilePath.value; // showPreview.value = true; // uni.hideLoading(); // }).catch(err => { // console.error('H5 PDF生成失败:', err); // uni.hideLoading(); // uni.showToast({ title: '生成失败', icon: 'none' }); // }); // #endif }; // 处理WebView消息 const handleWebviewMessage = (e: any) => { console.log('收到WebView消息:', e.detail); }; </script> <style scoped> .container { position: relative; height: 100vh; overflow: hidden; } #targetWebview { width: 100%; height: calc(100vh - 100px); } .bottom-action-area { position: fixed; bottom: 0; left: 0; right: 0; z-index: 100; background-color: #007aff; padding: 15px; display: flex; justify-content: center; padding-bottom: calc(10rpx + constant(safe-area-inset-bottom)); padding-bottom: calc(10rpx + env(safe-area-inset-bottom)); } .capture-btn { width: 100%; height: 90rpx; padding: 12px; background-color: #007aff; border-radius: 8px; display: flex; align-items: center; justify-content: center; } .btn-text { color: white; font-size: 14px; font-weight: 500; } /* PDF预览样式 */ .pdf-preview { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 1000; background-color: white; display: flex; flex-direction: column; } .preview-header { background-color: #007aff; padding: 15px; } .title-container { display: flex; justify-content: center; } .preview-title { color: white; font-size: 18px; font-weight: bold; } .preview-iframe { flex: 1; width: 100%; border: none; } .action-buttons { display: flex; padding: 15px; background-color: #f5f5f5; } .action-btn { flex: 1; padding: 12px; border-radius: 8px; text-align: center; font-weight: 500; } .cancel-btn { background-color: #f5f5f5; color: #333; margin-right: 10px; } .confirm-btn { background-color: #007aff; color: white; margin-left: 10px; } </style> 哪里的问题 为什么app端 webview的内容没有转换成pdf格式
08-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值