1346 "returns whether colorMapMode is equal to aMode" |
1356 "returns whether colorMapMode is equal to aMode" |
1347 |
1357 |
1348 ^colorMapMode = aMode |
1358 ^colorMapMode = aMode |
1349 ! |
1359 ! |
1350 |
1360 |
1351 colorMapMode: aMode value: aValue |
|
1352 "calculates a new color map for the image from aMode" |
|
1353 |
|
1354 |depth newColorMap newImage image newColors realColorMap oldFileName| |
|
1355 |
|
1356 imageEditView makeUndo. |
|
1357 |
|
1358 newColorMap := self class listOfColorMaps at: aMode. |
|
1359 depth := (newColorMap size log: 2) asInteger. |
|
1360 newImage := (Image implementorForDepth: depth) new. |
|
1361 oldFileName := self image fileName. |
|
1362 |
|
1363 Object errorSignal handle: |
|
1364 [:ex| |
|
1365 Object errorSignal handle: |
|
1366 [:ex| |
|
1367 imageEditView undo. |
|
1368 ^self warn: 'Convertation failed!!' |
|
1369 ] |
|
1370 do: |
|
1371 [ |
|
1372 self image colorsFromX:0 y:0 toX:(self image width-1) y:(self image height-1) do: |
|
1373 [:x :y :clr | |
|
1374 (newColorMap includes: clr) |
|
1375 ifTrue: [self image colorAtX:x y:y put:clr] |
|
1376 ifFalse: [self image colorAtX:x y:y put: self image colorMap first] |
|
1377 ]. |
|
1378 image := newImage fromImage: self image. |
|
1379 ]. |
|
1380 ] |
|
1381 do: |
|
1382 [ |
|
1383 image := newImage fromImage: self image |
|
1384 ]. |
|
1385 |
|
1386 (String fromString: aMode) reverse readStream nextWord reverse = 'mask' |
|
1387 ifTrue: |
|
1388 [ |
|
1389 image mask isNil |
|
1390 ifTrue: |
|
1391 [ |
|
1392 image mask: (Depth1Image fromImage: (image asThresholdMonochromeImage: 0.1)). |
|
1393 ]. |
|
1394 ] |
|
1395 ifFalse: |
|
1396 [ |
|
1397 image mask: nil. |
|
1398 ]. |
|
1399 realColorMap := OrderedCollection new. |
|
1400 image realColorMap do: |
|
1401 [:clr| |
|
1402 (realColorMap includes: clr) ifFalse: [realColorMap add: clr] |
|
1403 ]. |
|
1404 newColors := realColorMap copyFrom: 1 to: (newColorMap size min: realColorMap size). |
|
1405 newColorMap do: |
|
1406 [:clr| |
|
1407 ((newColors size < newColorMap size) and: [(newColors includes: clr) not]) |
|
1408 ifTrue: |
|
1409 [ |
|
1410 newColors add: clr |
|
1411 ] |
|
1412 ]. |
|
1413 image colorMap: newColors. |
|
1414 colorMapMode := aMode. |
|
1415 (imageEditView image: image) notNil |
|
1416 ifTrue: |
|
1417 [ |
|
1418 self image fileName: oldFileName. |
|
1419 self listOfColors contents: image colorMap. |
|
1420 self findColorMapMode. |
|
1421 self updateLabelsAndHistory. |
|
1422 ] |
|
1423 ! |
|
1424 |
|
1425 editMode: aMode |
1361 editMode: aMode |
1426 "returns whether editMode is equal to aMode" |
1362 "returns whether editMode is equal to aMode" |
1427 |
1363 |
1428 ^imageEditView editMode = aMode |
1364 ^imageEditView editMode = aMode |
1429 ! |
1365 ! |
1516 postOpenAction notNil ifTrue: [postOpenAction value]. |
1452 postOpenAction notNil ifTrue: [postOpenAction value]. |
1517 |
1453 |
1518 super postOpenWith:aBuilder |
1454 super postOpenWith:aBuilder |
1519 |
1455 |
1520 "Modified: / 26.7.1998 / 12:32:55 / cg" |
1456 "Modified: / 26.7.1998 / 12:32:55 / cg" |
|
1457 ! ! |
|
1458 |
|
1459 !ImageEditor methodsFor:'user actions - colormap'! |
|
1460 |
|
1461 colorMapMode:aMode value: aValue |
|
1462 "calculates a new color map for the image from aMode" |
|
1463 |
|
1464 |depth numColors newColorMap newImage |
|
1465 oldImage image newColors realColorMap oldFileName |
|
1466 usedColors useNearest usageCounts tmpBits tmpMap| |
|
1467 |
|
1468 self withExecuteCursorDo:[ |
|
1469 oldImage := self image. |
|
1470 |
|
1471 newColorMap := self class listOfColorMaps at:aMode. |
|
1472 depth := (newColorMap size log: 2) asInteger. |
|
1473 |
|
1474 useNearest := false. |
|
1475 (self confirm:'Keep colormap (or use standard)') ifTrue:[ |
|
1476 "/ keep the colormap |
|
1477 depth > oldImage depth ifTrue:[ |
|
1478 "/ easy - simply copy the part |
|
1479 numColors := 1 bitShift:oldImage depth. |
|
1480 0 to:numColors-1 do:[:pixel | |
|
1481 newColorMap at:(pixel+1) put:(oldImage colorFromValue:pixel) |
|
1482 ]. |
|
1483 ] ifFalse:[ |
|
1484 "/ see if all used color fit the new colormap |
|
1485 usedColors := oldImage usedColors. |
|
1486 usedColors := usedColors asArray. |
|
1487 usedColors size <= (1 bitShift:depth) ifTrue:[ |
|
1488 "/ yea - just install them |
|
1489 usedColors keysAndValuesDo:[:idx :clr | |
|
1490 newColorMap at:idx put:clr |
|
1491 ] |
|
1492 ] ifFalse:[ |
|
1493 "/ copy over those that are most often used. |
|
1494 oldImage depth ~~ 8 ifTrue:[ |
|
1495 tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height). |
|
1496 oldImage bits |
|
1497 expandPixels:(oldImage depth) |
|
1498 width:oldImage width |
|
1499 height:oldImage height |
|
1500 into:tmpBits |
|
1501 mapping:nil. |
|
1502 ] ifFalse:[ |
|
1503 tmpBits := oldImage bits |
|
1504 ]. |
|
1505 usageCounts := tmpBits usageCounts. |
|
1506 tmpMap := Array new:usageCounts size. |
|
1507 oldImage colorMap asArray keysAndValuesDo:[:i :clr | |
|
1508 tmpMap at:i put:clr |
|
1509 ]. |
|
1510 usageCounts sort:[:a :b | a > b] with:tmpMap. |
|
1511 |
|
1512 1 to:(1 bitShift:depth) do:[:idx | |
|
1513 newColorMap at:idx put:(tmpMap at:idx) |
|
1514 ]. |
|
1515 |
|
1516 useNearest := Dialog |
|
1517 confirmWithCancel:('Image requires %1 colors.\ColorMap has only space for %2\\Use nearest (or map to black) ?' |
|
1518 bindWith:usedColors size |
|
1519 with:(1 bitShift:depth)) withCRs |
|
1520 labels:#('cancel' 'black' 'nearest'). |
|
1521 useNearest isNil ifTrue:[ |
|
1522 ^ self "/ cancel |
|
1523 ]. |
|
1524 ] |
|
1525 ] |
|
1526 ] ifFalse:[ |
|
1527 "/ standard colormap |
|
1528 ]. |
|
1529 |
|
1530 imageEditView makeUndo. |
|
1531 |
|
1532 newImage := (Image implementorForDepth: depth) new. |
|
1533 oldFileName := oldImage fileName. |
|
1534 |
|
1535 Object errorSignal handle: |
|
1536 [:ex| |
|
1537 Object errorSignal handle: |
|
1538 [:ex| |
|
1539 imageEditView undo. |
|
1540 ^self warn: 'Conversion failed!!' |
|
1541 ] |
|
1542 do: |
|
1543 [ |
|
1544 newImage := (Image implementorForDepth: depth) new. |
|
1545 newImage width:oldImage width height:oldImage height depth:depth. |
|
1546 newImage colorMap:newColorMap. |
|
1547 newImage photometric:#palette. |
|
1548 newImage bits:(ByteArray new:(newImage bytesPerRow * newImage height)). |
|
1549 |
|
1550 oldImage colorsFromX:0 y:0 toX:(oldImage width-1) y:(oldImage height-1) do: |
|
1551 [:x :y :clr | |
|
1552 |newColor| |
|
1553 |
|
1554 (newColorMap includes:clr) |
|
1555 ifTrue: [newColor := clr] |
|
1556 ifFalse: [ |
|
1557 useNearest ifTrue:[ |
|
1558 newColor := clr nearestIn:newColorMap |
|
1559 ] ifFalse:[ |
|
1560 newColor := oldImage colorMap first |
|
1561 ] |
|
1562 ]. |
|
1563 newImage colorAtX:x y:y put:newColor. |
|
1564 ]. |
|
1565 image := newImage |
|
1566 ]. |
|
1567 ] |
|
1568 do: |
|
1569 [ |
|
1570 image := newImage fromImage: oldImage |
|
1571 ]. |
|
1572 |
|
1573 (String fromString: aMode) reverse readStream nextWord reverse = 'mask' |
|
1574 ifTrue: |
|
1575 [ |
|
1576 image mask isNil |
|
1577 ifTrue: |
|
1578 [ |
|
1579 image mask: (Depth1Image fromImage: (image asThresholdMonochromeImage: 0.1)). |
|
1580 ]. |
|
1581 ] |
|
1582 ifFalse: |
|
1583 [ |
|
1584 image mask: nil. |
|
1585 ]. |
|
1586 realColorMap := OrderedCollection new. |
|
1587 image realColorMap do: |
|
1588 [:clr| |
|
1589 (realColorMap includes: clr) ifFalse: [realColorMap add: clr] |
|
1590 ]. |
|
1591 newColors := realColorMap copyFrom: 1 to: (newColorMap size min: realColorMap size). |
|
1592 newColorMap do: |
|
1593 [:clr| |
|
1594 ((newColors size < newColorMap size) and: [(newColors includes: clr) not]) |
|
1595 ifTrue: |
|
1596 [ |
|
1597 newColors add: clr |
|
1598 ] |
|
1599 ]. |
|
1600 image colorMap: newColors. |
|
1601 colorMapMode := aMode. |
|
1602 |
|
1603 (imageEditView image: image) notNil ifTrue: |
|
1604 [ |
|
1605 image fileName: oldFileName. |
|
1606 self listOfColors contents: image colorMap. |
|
1607 self findColorMapMode. |
|
1608 self updateLabelsAndHistory. |
|
1609 ] |
|
1610 ] |
|
1611 |
|
1612 "Modified: / 28.7.1998 / 21:42:14 / cg" |
|
1613 ! |
|
1614 |
|
1615 compressColorMap |
|
1616 "calculates a new color map for the image, using only used colors" |
|
1617 |
|
1618 |depth numColors newColorMap newImage |
|
1619 oldImage newColors realColorMap oldFileName |
|
1620 usedColors useNearest oldToNew oldBits newBits tmpBits| |
|
1621 |
|
1622 oldImage := self image. |
|
1623 depth := oldImage depth. |
|
1624 |
|
1625 oldImage photometric ~~ #palette ifTrue:[ |
|
1626 self information:'Only palette images have colormaps.'. |
|
1627 ^ self |
|
1628 ]. |
|
1629 |
|
1630 usedColors := oldImage usedColors. |
|
1631 usedColors size == (1 bitShift:depth) ifTrue:[ |
|
1632 self information:'All colors are used - no compression.'. |
|
1633 ^ self |
|
1634 ]. |
|
1635 usedColors size == oldImage colorMap size ifTrue:[ |
|
1636 self information:'Colormap already compressed - no compression.'. |
|
1637 ^ self |
|
1638 ]. |
|
1639 |
|
1640 imageEditView makeUndo. |
|
1641 |
|
1642 self information:('%1 colors used.' bindWith:usedColors size). |
|
1643 |
|
1644 self withExecuteCursorDo:[ |
|
1645 newColorMap := Array new:usedColors size. |
|
1646 |
|
1647 "/ translation table |
|
1648 oldToNew := ByteArray new:(1 bitShift:depth). |
|
1649 newColorMap := usedColors asArray. |
|
1650 oldImage colorMap asArray keysAndValuesDo:[:oldIdx :clr | |
|
1651 |newPixel| |
|
1652 |
|
1653 (usedColors includes:clr) ifTrue:[ |
|
1654 newPixel := newColorMap indexOf:clr. |
|
1655 oldToNew at:oldIdx put:newPixel-1. |
|
1656 ] |
|
1657 ]. |
|
1658 |
|
1659 oldBits := oldImage bits. |
|
1660 newBits := ByteArray new:(oldBits size). |
|
1661 depth ~~ 8 ifTrue:[ |
|
1662 "/ expand/compress can only handle 8bits |
|
1663 tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height). |
|
1664 oldBits |
|
1665 expandPixels:depth |
|
1666 width:oldImage width |
|
1667 height:oldImage height |
|
1668 into:tmpBits |
|
1669 mapping:oldToNew. |
|
1670 tmpBits |
|
1671 compressPixels:depth |
|
1672 width:oldImage width |
|
1673 height:oldImage height |
|
1674 into:newBits |
|
1675 mapping:nil |
|
1676 ] ifFalse:[ |
|
1677 oldBits |
|
1678 expandPixels:depth |
|
1679 width:oldImage width |
|
1680 height:oldImage height |
|
1681 into:newBits |
|
1682 mapping:oldToNew. |
|
1683 ]. |
|
1684 |
|
1685 newImage := oldImage species new |
|
1686 width:oldImage width |
|
1687 height:oldImage height |
|
1688 depth:depth |
|
1689 fromArray:newBits. |
|
1690 |
|
1691 newImage colorMap:newColorMap. |
|
1692 newImage fileName:oldImage fileName. |
|
1693 newImage mask:(oldImage mask copy). |
|
1694 |
|
1695 (imageEditView image:newImage) notNil ifTrue: |
|
1696 [ |
|
1697 self listOfColors contents: newImage colorMap. |
|
1698 self findColorMapMode. |
|
1699 self updateLabelsAndHistory. |
|
1700 ] |
|
1701 ] |
|
1702 |
|
1703 "Created: / 28.7.1998 / 20:03:11 / cg" |
|
1704 "Modified: / 28.7.1998 / 21:36:17 / cg" |
1521 ! ! |
1705 ! ! |
1522 |
1706 |
1523 !ImageEditor methodsFor:'user actions - editing'! |
1707 !ImageEditor methodsFor:'user actions - editing'! |
1524 |
1708 |
1525 doBrowseClass |
1709 doBrowseClass |