java根据RGB值判断深色与浅色

本文介绍了一种通过计算RGB值来判断颜色深浅的方法。利用公式:0.299*R + 0.587*G + 0.114*B与阈值192比较,可以有效地区分颜色的深浅。

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

 /**
     * 根据RGB值判断 深色与浅色
     * @param r
     * @param g
     * @param b
     * @return
     */
    public static boolean isDark(Double r,Double g,Double b){
        if(r*0.299 + g*0.578 + b*0.114 >= 192){ //浅色
            return false;
        }else{  //深色
            return true;
        }
    }

 

<think>在ApachePOI中处理Excel文件(xlsx格式)时,主题信息存储在`ThemesTable`对象中。主题定义了颜色方案(包括背景色)。然而,Excel中的背景色可能直接应用在单元格样式上,也可能通过主题颜色引用。要获取主题中的背景色,我们需要访问主题的颜色方案。###步骤1.**获取工作簿的主题**:通过`XSSFWorkbook`获取`ThemesTable`。2.**从主题中提取颜色方案**:主题中的颜色方案包含一系列预定义的颜色(如`dark1`,`light1`,`accent1`等)。3.**解析颜色方案中的颜色**:颜色方案中的颜色以`CTColor`形式存在,我们需要将其转换为Java的`Color`对象。###代码实现```javaimportorg.apache.poi.xssf.model.ThemesTable;importorg.apache.poi.xssf.usermodel.*;importorg.apache.poi.openxml4j.exceptions.InvalidFormatException;importorg.openxmlformats.schemas.drawingml.x2006.main.CTColor;importorg.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme;importorg.apache.poi.util.Units;importjava.io.FileInputStream;importjava.io.IOException;importjava.awt.Color;publicclassExcelThemeColorExtractor{publicstaticvoidmain(String[]args)throwsIOException,InvalidFormatException{StringfilePath="workbook.xlsx";try(FileInputStreamfileIn=newFileInputStream(filePath);XSSFWorkbookworkbook=newXSSFWorkbook(fileIn)){//获取主题表ThemesTablethemes=workbook.getTheme();if(themes==null){System.out.println("工作簿没有定义主题。");return;}//获取颜色方案CTColorSchemecolorScheme=themes.getTheme().getThemeElements().getClrScheme();//提取背景色:在Excel主题中,背景色通常对应'dk1'(dark1)或'lt1'(light1)Colorbg1=getColorFromScheme(colorScheme,"bg1");Colorbg2=getColorFromScheme(colorScheme,"bg2");System.out.println("主题背景色1(bg1):"+formatColor(bg1));System.out.println("主题背景色2(bg2):"+formatColor(bg2));}}privatestaticColorgetColorFromScheme(CTColorSchemecolorScheme,StringcolorName){//遍历颜色方案中的所有颜色定义for(CTColorcolor:colorScheme.getColorArray()){if(colorName.equals(color.getVal())){//获取颜色的具体(可能是srgbClr,sysClr,schemeClr等)if(color.isSetSrgbClr()){byte[]rgb=color.getSrgbClr().getVal();returnnewColor(rgb[0]&0xFF,//转换为无符号字节rgb[1]&0xFF,rgb[2]&0xFF);}elseif(color.isSetSysClr()){byte[]rgb=color.getSysClr().getLastClr();returnnewColor(rgb[0]&0xFF,rgb[1]&0xFF,rgb[2]&0xFF);}}}returnnull;}privatestaticStringformatColor(Colorcolor){if(color==null)return"未定义";returnString.format("RGB(%d,%d,%d)",color.getRed(),color.getGreen(),color.getBlue());}}```###代码解释1.**获取ThemesTable**:```javaThemesTablethemes=workbook.getTheme();```如果工作簿没有定义主题,则返回`null`。2.**获取颜色方案**:```javaCTColorSchemecolorScheme=themes.getTheme().getThemeElements().getClrScheme();````CTColorScheme`对象包含了主题中定义的所有颜色。3.**遍历颜色定义**:颜色方案中包含多个颜色定义(如`dk1`,`lt1`,`accent1`等)。在Excel主题中,背景色通常由`bg1`和`bg2`表示,但注意:在标准的Office主题中,颜色名称是固定的,包括:-`dk1`:主文字颜色(深色)-`lt1`:主文字颜色(浅色)-`dk2`:次文字颜色(深色)-`lt2`:次文字颜色(浅色)-`accent1`到`accent6`:强调色-`hlink`:超链接颜色-`folHlink`:已访问的超链接颜色-`bg1`:背景1-`bg2`:背景2-`tx1`:文字1-`tx2`:文字24.**解析颜色**:-`srgbClr`:使用RGB颜色,直接读取。-`sysClr`:系统颜色,通常取其最后定义的颜色(`lastClr`)。5.**处理颜色**:由于`byte`在Java中是有符号的,我们需要通过`&0xFF`将其转换为无符号整数(0-255)。###注意事项-**颜色名称的差异**:在Excel中,主题颜色名称可能和PowerPoint有所不同。上述代码中我们尝试获取`bg1`和`bg2`,但实际中主题颜色名称是固定的(如`lt1`,`dk1`等)。背景色通常不是直接存储在主题颜色中,而是通过应用主题后,在样式中引用这些颜色。所以,获取主题中的背景色可能并不直接对应工作表的背景色,而是主题定义的一部分。-**实际背景色**:工作表的背景色可能通过单元格样式设置,也可能通过工作表背景图片设置。要获取实际显示的背景色,可能需要检查单元格的填充色(`CellStyle.getFillBackgroundColor()`)或者工作表的背景设置(`Sheet.getBackgroundImage()`等)。-**主题引用**:单元格样式可能引用主题颜色(如“主文字颜色”、“强调色1”等),此时需要根据索引从主题颜色方案中获取实际颜色。###获取单元格背景色的实际应用如果你需要获取单元格的实际背景色(考虑到可能引用了主题颜色),可以使用以下方法:```javaXSSFCellcell=...;//获取单元格XSSFCellStylestyle=cell.getCellStyle();XSSFColorcolor=style.getFillBackgroundColorColor();if(color!=null){//如果颜色是主题颜色,则从主题中获取实际颜色byte[]rgb=color.getRGB();if(rgb!=null){ColorawtColor=newColor(rgb[0]&0xFF,rgb[1]&0xFF,rgb[2]&0xFF);}elseif(color.isIndexed()){//处理索引颜色(如自动颜色)}elseif(color.getIndexed()==64){//64表示自动颜色(通常为白色或黑色,取决于背景)}elseif(color.isThemed()){//获取主题颜色索引intthemeIndex=color.getTheme();//从主题中获取颜色byte[]themeRgb=themes.getThemeColor(themeIndex);//注意:主题颜色可能还带有色调(tint),需要调整doubletint=color.getTint();//应用色调调整(这里需要额外的处理)//然后将themeRgb转换为Color}}```###相关问题§§相关问题§§:1.如何根据主题索引和色调(tint)计算最终的颜色?2.在Excel中如何设置单元格的背景色为主题颜色?3.如何处理条件格式设置的背景色?4.如何获取工作表的整体背景色(非单元格背景)?</think># 在 Apache POI 中获取 Excel 主题背景色 在 Apache POI 中处理 Excel 文件时,主题背景色可以通过访问 `ThemesTable` 对象获取。Excel 的主题定义了文档的整体配色方案,包括背景色。以下是完整的解决方案: ## 完整代码实现 ```java import org.apache.poi.xssf.usermodel.*; import org.apache.poi.openxml4j.opc.PackagePart; import org.openxmlformats.schemas.drawingml.x2006.main.*; import org.openxmlformats.schemas.drawingml.x2006.theme.CTOfficeStyleSheet; import java.io.FileInputStream; import java.awt.Color; import java.util.List; public class ExcelThemeBackgroundExtractor { public static void main(String[] args) throws Exception { try (FileInputStream fis = new FileInputStream("workbook.xlsx"); XSSFWorkbook workbook = new XSSFWorkbook(fis)) { // 1. 获取主题表 XSSFTheme theme = workbook.getTheme(); if (theme == null) { System.out.println("工作簿未定义主题"); return; } // 2. 获取主题背景色 Color bgColor = getThemeBackgroundColor(theme); if (bgColor != null) { System.out.println("主题背景色: RGB(" + bgColor.getRed() + ", " + bgColor.getGreen() + ", " + bgColor.getBlue() + ")"); } else { System.out.println("未找到主题背景色定义"); } // 3. 获取所有主题颜色 System.out.println("\n主题颜色方案:"); List<Color> themeColors = getThemeColorScheme(theme); for (int i = 0; i < themeColors.size(); i++) { Color color = themeColors.get(i); System.out.printf("颜色%d: RGB(%d, %d, %d)%n", i+1, color.getRed(), color.getGreen(), color.getBlue()); } } } /** * 从主题中获取背景色 */ public static Color getThemeBackgroundColor(XSSFTheme theme) { // 获取主题的XML定义 CTOfficeStyleSheet themeXml = theme.getTheme(); CTColorScheme colorScheme = themeXml.getThemeElements().getClrScheme(); // 背景色通常存储在bg1或bg2中 Color bg1 = getColorFromScheme(colorScheme, "bg1"); Color bg2 = getColorFromScheme(colorScheme, "bg2"); return bg1 != null ? bg1 : bg2; } /** * 获取主题中的所有颜色 */ public static List<Color> getThemeColorScheme(XSSFTheme theme) { CTColorScheme colorScheme = theme.getTheme().getThemeElements().getClrScheme(); return List.of( getColorFromScheme(colorScheme, "dk1"), getColorFromScheme(colorScheme, "lt1"), getColorFromScheme(colorScheme, "dk2"), getColorFromScheme(colorScheme, "lt2"), getColorFromScheme(colorScheme, "accent1"), getColorFromScheme(colorScheme, "accent2"), getColorFromScheme(colorScheme, "accent3"), getColorFromScheme(colorScheme, "accent4"), getColorFromScheme(colorScheme, "accent5"), getColorFromScheme(colorScheme, "accent6"), getColorFromScheme(colorScheme, "hlink"), getColorFromScheme(colorScheme, "folHlink") ); } /** * 从颜色方案中获取特定颜色 */ private static Color getColorFromScheme(CTColorScheme colorScheme, String colorName) { for (CTColor color : colorScheme.getColorArray()) { if (colorName.equals(color.getVal())) { // 检查颜色类型 if (color.isSetSrgbClr()) { CTSRgbColor rgbColor = color.getSrgbClr(); byte[] rgb = rgbColor.getVal(); return new Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF); } else if (color.isSetSysClr()) { CTSystemColor sysColor = color.getSysClr(); byte[] rgb = sysColor.getLastClr(); return new Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF); } else if (color.isSetHslClr()) { // 处理HSL颜色(较少见) CTHslColor hslColor = color.getHslClr(); return convertHslToRgb( hslColor.getHue() / 60000f, // 0-60000 → 0-360 hslColor.getSat() / 100000f, // 0-100000 → 0-1 hslColor.getLum() / 100000f // 0-100000 → 0-1 ); } } } return null; } /** * 将HSL颜色转换为RGB */ private static Color convertHslToRgb(float h, float s, float l) { float r, g, b; if (s == 0) { r = g = b = l; // 灰度 } else { float q = l < 0.5f ? l * (1 + s) : l + s - l * s; float p = 2 * l - q; r = hueToRgb(p, q, h + 1f/3); g = hueToRgb(p, q, h); b = hueToRgb(p, q, h - 1f/3); } return new Color(r, g, b); } private static float hueToRgb(float p, float q, float t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1f/6) return p + (q - p) * 6 * t; if (t < 1f/2) return q; if (t < 2f/3) return p + (q - p) * (2f/3 - t) * 6; return p; } } ``` ## 代码解释 ### 1. 获取主题对象 ```java XSSFTheme theme = workbook.getTheme(); ``` - `XSSFWorkbook` 代表 Excel 工作簿 - `getTheme()` 方法返回工作簿的主题对象 ### 2. 获取背景色 ```java public static Color getThemeBackgroundColor(XSSFTheme theme) { CTOfficeStyleSheet themeXml = theme.getTheme(); CTColorScheme colorScheme = themeXml.getThemeElements().getClrScheme(); Color bg1 = getColorFromScheme(colorScheme, "bg1"); Color bg2 = getColorFromScheme(colorScheme, "bg2"); return bg1 != null ? bg1 : bg2; } ``` - Excel 主题背景色通常存储在 `bg1` (背景1) 或 `bg2` (背景2) 中 - 优先返回 `bg1`,如果没有则返回 `bg2` ### 3. 颜色解析逻辑 ```java private static Color getColorFromScheme(CTColorScheme colorScheme, String colorName) { for (CTColor color : colorScheme.getColorArray()) { if (colorName.equals(color.getVal())) { // 检查颜色类型 if (color.isSetSrgbClr()) { // 处理RGB颜色 } else if (color.isSetSysClr()) { // 处理系统颜色 } else if (color.isSetHslClr()) { // 处理HSL颜色 } } } return null; } ``` Excel 主题颜色可能以三种格式存储: 1. **RGB 颜色** (`srgbClr`): ```java CTSRgbColor rgbColor = color.getSrgbClr(); byte[] rgb = rgbColor.getVal(); return new Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF); ``` 2. **系统颜色** (`sysClr`): ```java CTSystemColor sysColor = color.getSysClr(); byte[] rgb = sysColor.getLastClr(); return new Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF); ``` 3. **HSL 颜色** (`hslClr`): ```java CTHslColor hslColor = color.getHslClr(); return convertHslToRgb( hslColor.getHue() / 60000f, hslColor.getSat() / 100000f, hslColor.getLum() / 100000f ); ``` ### 4. Excel 主题颜色方案 Excel 主题包含12种标准颜色: | 颜色名称 | 描述 | |------------|--------------------------| | `dk1` | 深色文字1 | | `lt1` | 浅色文字1 | | `dk2` | 深色文字2 | | `lt2` | 浅色文字2 | | `accent1` | 强调文字颜色1 | | `accent2` | 强调文字颜色2 | | `accent3` | 强调文字颜色3 | | `accent4` | 强调文字颜色4 | | `accent5` | 强调文字颜色5 | | `accent6` | 强调文字颜色6 | | `hlink` | 超链接颜色 | | `folHlink` | 已访问的超链接颜色 | | `bg1` | 背景1 (主背景色) | | `bg2` | 背景2 (次背景色) | ## 处理主题引用 在 Excel 中,单元格样式通常引用主题颜色而非直接指定 RGB 。获取实际显示的颜色需要解析主题引用: ```java public static Color getCellBackgroundColor(XSSFCell cell) { XSSFCellStyle style = cell.getCellStyle(); XSSFColor color = style.getFillBackgroundColorColor(); if (color == null) { return null; // 无背景色 } // 检查是否是主题颜色 if (color.isIndexedThemeColor()) { int themeIndex = color.getIndexed(); return getThemeColorByIndex(cell.getSheet().getWorkbook().getTheme(), themeIndex); } // 直接返回RGB颜色 byte[] rgb = color.getRGB(); if (rgb != null && rgb.length >= 3) { return new Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF); } return null; } private static Color getThemeColorByIndex(XSSFTheme theme, int themeIndex) { // Excel 主题颜色索引映射 String[] colorNames = { "lt1", "dk1", "lt2", "dk2", "accent1", "accent2", "accent3", "accent4", "accent5", "accent6", "hlink", "folHlink" }; if (themeIndex >= 0 && themeIndex < colorNames.length) { return getColorFromScheme( theme.getTheme().getThemeElements().getClrScheme(), colorNames[themeIndex] ); } return null; } ``` ## 注意事项 1. **主题层级**: - 工作簿级主题 (`XSSFWorkbook.getTheme()`) - 工作表级主题 (较少使用) 2. **颜色格式**: - Excel 主题颜色可能使用 RGB、系统颜色或 HSL 格式 - 系统颜色在不同操作系统上可能有不同表现 3. **空主题处理**: - 如果工作簿没有定义主题,`workbook.getTheme()` 返回 `null` - 此时应使用默认颜色方案 4. **性能考虑**: - 对于大型工作簿,缓存主题信息 - 避免重复解析 XML 对象 ## 示例输出 ``` 主题背景色: RGB(240, 240, 240) 主题颜色方案: 颜色1: RGB(0, 0, 0) // dk1 颜色2: RGB(255, 255, 255) // lt1 颜色3: RGB(79, 98, 40) // dk2 颜色4: RGB(210, 225, 221) // lt2 颜色5: RGB(79, 129, 189) // accent1 颜色6: RGB(192, 80, 77) // accent2 颜色7: RGB(155, 187, 89) // accent3 颜色8: RGB(128, 100, 162) // accent4 颜色9: RGB(247, 150, 70) // accent5 颜色10: RGB(84, 130, 53) // accent6 颜色11: RGB(0, 112, 192) // hlink 颜色12: RGB(112, 48, 160) // folHlink ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赛赛liangks

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值